Transición de la imagen de fondo CSS3

121

Estoy tratando de hacer un efecto de "fundido de entrada y salida" utilizando la transición CSS. Pero no puedo hacer que esto funcione con la imagen de fondo ...

El CSS:

.title a {
    display: block;
    width: 340px;
    height: 338px;
    color: black;
    background: transparent;
    /* TRANSITION */
    -webkit-transition: background 1s;
    -moz-transition: background 1s;
    -o-transition: background 1s;
    transition: background 1s;
}

.title a:hover {
    background: transparent;
    background: url(https://lh3.googleusercontent.com/-p1nr1fkWKUo/T0zUp5CLO3I/AAAAAAAAAWg/jDiQ0cUBuKA/s800/red-pattern.png) repeat;
    /* TRANSITION */
    -webkit-transition: background 1s;
    -moz-transition: background 1s;
    -o-transition: background 1s;
    transition: background 1s;
}​

Eche un vistazo: http://jsfiddle.net/AK3La/

Nick Zani
fuente

Respuestas:

104

Puede hacer la transición background-image. Use el CSS a continuación en el imgelemento:

-webkit-transition: background-image 0.2s ease-in-out;
transition: background-image 0.2s ease-in-out;

Esto es compatible de forma nativa con Chrome, Opera y Safari. Firefox aún no lo ha implementado ( bugzil.la ). No estoy seguro de IE.

Hengjie
fuente
105
background-imageno es una propiedad animable ( w3.org/TR/css3-transitions/#animatable-properties ), por lo que su solución no es compatible con el estándar.
TLindig
12
Esta no es una solución: FF e IE no lo admiten y, como se indicó anteriormente, no es una propiedad que la especificación dice que debería ser compatible.
Sentinel
Consulte también el desarrollo actual en Fx: bugzilla.mozilla.org/show_bug.cgi?id=546052
Volker E.
2
@TLindig Debería ser una propiedad animable.
3
La propiedad animable es background, y esto es lo que debería usarse (funciona en Chrome para mí). Tal vez la especificación (o el impl) haya cambiado desde que se publicó la pregunta
fps
37

La solución (que encontré yo mismo) es un truco ninja, te puedo ofrecer dos formas:

primero debe crear un "contenedor" para el <img>, contendrá los estados normal y de desplazamiento al mismo tiempo:

<div class="images-container">
    <img src="http://lorempixel.com/400/200/animals/9/">
    <img src="http://lorempixel.com/400/200/animals/10/">
</div>

Básicamente, debes ocultar el estado "normal" y mostrar su "desplazamiento" cuando lo colocas.

y eso es todo, espero que alguien lo encuentre útil.

Ruffo
fuente
Buena solucion. Al experimentar con la primera muestra, noté que si aumenta la duración de la transición a 4 segundos, puede ver un salto muy notable cuando el índice z cambia en el medio de la transición. Al menos en Chrome 35, puede cambiar la sincronización del interruptor de índice z y limpiar la transición cambiando el valor de la propiedad a "facilidad de 4 segundos, índice z 1 ms" ( jsfiddle.net/eD2zL/330 ).
Neal Stublen
2
@NealS. tienes razón. Sin embargo, esta respuesta tiene 2 años, eliminaría el índice z, parece innecesario. Las imágenes solo deben estar en orden.
Ruffo
Muchas gracias. Tu solución es muy útil para mí.
Slam
¿Es posible una "carga diferida" si utilizo esta solución?
Daniel
16

He descubierto una solución que funcionó para mí ...

Si tiene un elemento de lista (o div) que contiene solo el enlace, digamos que esto es para enlaces sociales en su página a Facebook, Twitter, etc. y estás usando una imagen de sprite, puedes hacer esto:

<li id="facebook"><a href="facebook.com"></a></li>

Convierte el fondo "li" en tu imagen de botón

#facebook {
   width:30px;
   height:30px;
   background:url(images/social) no-repeat 0px 0px;
}

Luego, haga que la imagen de fondo del enlace sea el estado de desplazamiento del botón. También agregue el atributo de opacidad a esto y configúrelo en 0.

#facebook a {
   display:inline-block;
   background:url(images/social) no-repeat 0px -30px;
   opacity:0;
}

Ahora todo lo que necesita es "opacidad" debajo de "a: hover" y establecer esto en 1.

#facebook a:hover {
   opacity:1;
}

Agregue los atributos de transición de opacidad para cada navegador a "a" y "a: hover" para que el CSS final se vea así:

#facebook {
   width:30px;
   height:30px;
   background:url(images/social) no-repeat 0px 0px;
}
#facebook a {
   display:inline-block;
   background:url(images/social) no-repeat 0px -30px;
   opacity:0;
   -webkit-transition: opacity 200ms linear;
   -moz-transition: opacity 200ms linear;
   -o-transition: opacity 200ms linear;
   -ms-transition: opacity 200ms linear;
   transition: opacity 200ms linear;
}
#facebook a:hover {
   opacity:1;
   -webkit-transition: opacity 200ms linear;
   -moz-transition: opacity 200ms linear;
   -o-transition: opacity 200ms linear;
   -ms-transition: opacity 200ms linear;
   transition: opacity 200ms linear;
}

Si lo expliqué correctamente, debería permitirle tener un botón de imagen de fondo que se desvanece, ¡espero que al menos ayude!

Austin Parrish Thomas
fuente
3
También hice una versión en video tutorial. youtube.com/watch?v=6ieR5ApVpr0
Austin Parrish Thomas
AFAIK, no deberías necesitar especificar las transiciones en la pseudoclase flotante; la definición de transición para el tipo de etiqueta de anclaje se trasladará al comportamiento de desplazamiento, todo lo que necesita cambiar es la opacidad. Tenga en cuenta que este ejemplo funciona bien porque los estilos se aplican directamente a los ID / tipos de etiquetas; si hace esto con clases, debe asegurarse de no agregar ni eliminar la clase con la transición definida.
KeithS
13

Puede usar un pseudo elemento para obtener el efecto que desea, como lo hice en ese Fiddle .

CSS:

.title a {
    display: block;
    width: 340px;
    height: 338px;
    color: black;
    position: relative;
}
.title a:after {
    background: url(https://lh3.googleusercontent.com/-p1nr1fkWKUo/T0zUp5CLO3I/AAAAAAAAAWg/jDiQ0cUBuKA/s800/red-pattern.png) repeat;
    content: "";
    opacity: 0;
    width: inherit;
    height: inherit;
    position: absolute;
    top: 0;
    left: 0;
    /* TRANSISITION */
    transition: opacity 1s ease-in-out;
    -webkit-transition: opacity 1s ease-in-out;
    -moz-transition: opacity 1s ease-in-out;
    -o-transition: opacity 1s ease-in-out;
}
.title a:hover:after{   
    opacity: 1;
}

HTML:

<div class="title">
    <a href="#">HYPERLINK</a>
</div>
MaxCloutier
fuente
2
Esto funciona muy bien, pero puede tener 2 problemas: 1) si no ve el :afterelemento, intente configurar widthy heightcomo en 100%lugar de inherit, 2) si background-imagerealmente se muestra en primer plano , use un índice negativo para el :afterelemento:z-index: -1;
Radek Pech
9

Si puede usar jQuery, puede probar el complemento BgSwitcher para cambiar la imagen de fondo con efectos, es muy fácil de usar.

Por ejemplo :

$('.bgSwitch').bgswitcher({
        images: ["style/img/bg0.jpg","style/img/bg1.jpg","style/img/bg2.jpg"],
        effect: "fade",
        interval: 10000
});

Y agregue su propio efecto, vea agregar tipos de efectos

MaxDhn
fuente
Gracias, he resuelto el problema con la animación del cambio de fondo de la tabla con el uso de este complemento.
userlond
4

Pruebe esto, hará que la animación de fondo funcione en la web pero la aplicación móvil híbrida no funcione

@-webkit-keyframes breath {
 0%   {  background-size: 110% auto; }
 50%  {  background-size: 140% auto; }
 100% {  background-size: 110% auto; }      
}
body {
   -webkit-animation: breath 15s linear infinite;
   background-image: url(images/login.png);
    background-size: cover;
}
Hesham Nasser
fuente
4

Teniendo en cuenta que las imágenes de fondo no se pueden animar, creé una pequeña mezcla de SCSS que permite la transición entre 2 imágenes de fondo diferentes usando pseudo selectores antes y después . Están en diferentes capas de índice Z. El que está adelante comienza con opacidad 0 y se vuelve visible con el mouse.

También puede usar el mismo enfoque para crear animaciones con gradientes lineales.

scss

@mixin bkg-img-transition( $bkg1, $bkg2, $transTime:0.5s ){  
  position: relative;  
  z-index: 100; 
  &:before, &:after {
    background-size: cover;  
    content: '';    
    display: block;
    height: 100%;
    position: absolute;
    top: 0; left: 0;    
    width: 100%;    
    transition: opacity $transTime;
  }
  &:before {    
    z-index: -101;
    background-image: url("#{$bkg1}");    
  }
  &:after {    
    z-index: -100;
    opacity: 0;
    background-image: url("#{$bkg2}");    
  }
  &:hover {
     &:after{
       opacity: 1; 
     }
  }  
}

Ahora puedes usarlo simplemente con

@include bkg-img-transition("https://picsum.photos/300/300/?random","https://picsum.photos/g/300/300");

Puedes consultarlo aquí: https://jsfiddle.net/pablosgpacheco/01rmg0qL/

Pablo SG Pacheco
fuente
¡Muy buena solución! Me dio una mejor comprensión de cómo hacer un buen uso de los estados de elementos ': before' y ': after' como bonificación :-)
joronimo
3

Si animar opacityno es una opción, también puede animar background-size.

Por ejemplo, utilicé este CSS para configurar un backgound-imagecon un retraso.

.before {
  background-size: 0;
}

.after {
  transition: background 0.1s step-end;
  background-image: $path-to-image;
  background-size: 20px 20px;
}
shock_one
fuente
Si desea un efecto de atenuación de hacia .afteradentro .beforepara la imagen de fondo, debe establecer la imagen de fondo en el formato .before. De lo contrario, simplemente desaparecerá sin animación.
Radek Pech
2

Salam, esta respuesta solo funciona en Chrome, porque IE y FF admiten la transición de color.

No es necesario crear sus elementos HTML opacity:0, ya que algunas veces contienen texto y no es necesario duplicar sus elementos.

La pregunta con relación a un ejemplo en jsFiddle necesita un pequeño cambio, que es poner una imagen vacía en .title acomo background:url(link to an empty image);mismo que lo pones en .title a:hoverpero que sea imagen vacía, y el código funcionará.

.title a {
display: block;
width: 340px;
height: 338px;
color: black;
background: url(https://upload.wikimedia.org/wikipedia/commons/5/59/Empty.png) repeat;
/* TRANSISITION */
transition: background 1s;
-webkit-transition: background 1s;
-moz-transition: background 1s;
-o-transition: background 1s;
  }
  .title a:hover{   background: transparent;
   background: url(https://lh3.googleusercontent.com/-p1nr1fkWKUo/T0zUp5CLO3I/AAAAAAAAAWg/jDiQ0cUBuKA/s800/red-pattern.png) repeat;
/* TRANSISITION */
transition: background 1s;
-webkit-transition: background 1s;
-moz-transition: background 1s;
-o-transition: background 1s;
}

Mira esto https://jsfiddle.net/Tobasi/vv8q9hum/

Mohammed Suleiman
fuente
Todavía no funciona en Fire Fox o IE :(, pero se ve bien en Chrome
Mohammed Suleiman
1

Con la inspiradora publicación de Chris aquí:

https://css-tricks.com/different-transitions-for-hover-on-hover-off/

Me las arreglé para llegar a esto:

#banner
{
    display:block;
    width:100%;
    background-repeat:no-repeat;
    background-position:center bottom;
    background-image:url(../images/image1.jpg);
    /* HOVER OFF */
    @include transition(background-image 0.5s ease-in-out); 

    &:hover
    {
        background-image:url(../images/image2.jpg);
        /* HOVER ON */
        @include transition(background-image 0.5s ease-in-out); 
    }
}
Carol McKay
fuente
0

Estuve luchando con esto por un momento, primero usé una pila de imágenes una encima de la otra y cada tres segundos, estaba tratando de animar a la siguiente imagen de la pila y arrojar la imagen actual al final de la pila. Al mismo tiempo, estaba usando animaciones como se muestra arriba. No pude hacer que funcionara por mi vida.

Puede usar esta biblioteca que permite ** imagen de fondo con capacidad de presentación de diapositivas redimensionada dinámicamente ** usando jquery-backstretch.

https://github.com/jquery-backstretch/jquery-backstretch

Akhil Khanna
fuente