Transition d'image d'arrière-plan CSS3

122

J'essaye de faire un "fondu en fondu en sortie" en utilisant la transition CSS. Mais je ne peux pas faire fonctionner cela avec l'image d'arrière-plan ...

Le 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;
}​

Jetez un œil: http://jsfiddle.net/AK3La/

Nick Zani
la source

Réponses:

104

Vous pouvez faire la transition background-image. Utilisez le CSS ci-dessous sur l' imgélément:

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

Ceci est pris en charge nativement par Chrome, Opera et Safari. Firefox ne l'a pas encore implémenté ( bugzil.la ). Je ne suis pas sûr d'IE.

Hengjie
la source
106
background-imagen'est pas une propriété animable ( w3.org/TR/css3-transitions/#animatable-properties ), donc votre solution n'est pas conforme au standard.
TLindig
12
Ce n'est pas une solution - FF et IE ne le prennent pas en charge, et comme indiqué ci-dessus, ce n'est pas une propriété dont la spécification dit qu'elle devrait être prise en charge.
Sentinel
Voir aussi pour le développement actuel dans Fx: bugzilla.mozilla.org/show_bug.cgi?id=546052
Volker E.
2
@TLindig Cela devrait être une propriété animable.
3
La propriété animable est background, et c'est ce qui devrait être utilisé (cela fonctionne dans Chrome pour moi). Peut-être que la spécification (ou l'impl) a changé depuis la publication de la question
fps
37

La solution (que j'ai trouvée par moi-même) est une astuce ninja, je peux vous proposer deux moyens:

vous devez d'abord créer un "conteneur" pour le <img>, il contiendra les états normal et survolé en même temps:

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

En gros, vous devez masquer l'état «normal» et afficher leur «survol» lorsque vous le survolez

et c'est tout, j'espère que quelqu'un le trouvera utile.

Ruffo
la source
Belle solution. Lors de l'expérimentation avec le premier échantillon, j'ai remarqué que si vous augmentez la durée de transition à 4s, vous pouvez voir un saut très notable lorsque l'index z bascule au milieu de la transition. Au moins sur Chrome 35, vous pouvez modifier la synchronisation du commutateur z-index et nettoyer la transition en modifiant la valeur de la propriété sur "all 4s eas, z-index 1ms " ( jsfiddle.net/eD2zL/330 ).
Neal Stublen
2
@NealS. vous avez raison. Cette réponse a 2 ans, je supprimerais le z-index, cela semble inutile. Les images doivent juste être en ordre.
Ruffo
Merci beaucoup. Votre solution m'est très utile.
Slam le
Est-ce que le "chargement paresseux" est possible si j'utilise cette solution?
Daniel
16

J'ai trouvé une solution qui a fonctionné pour moi ...

Si vous avez un élément de liste (ou div) contenant uniquement le lien, et disons que c'est pour les liens sociaux sur votre page vers Facebook, Twitter, etc. et vous utilisez une image de sprite, vous pouvez le faire:

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

Faire de l'arrière-plan "li" l'image de votre bouton

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

Faites ensuite de l'image d'arrière-plan du lien l'état de survol du bouton. Ajoutez également l'attribut d'opacité à cela et définissez-le sur 0.

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

Maintenant, tout ce dont vous avez besoin est "opacity" sous "a: hover" et réglez ceci sur 1.

#facebook a:hover {
   opacity:1;
}

Ajoutez les attributs de transition d'opacité de chaque navigateur à "a" et "a: hover" pour que le css final ressemble à ceci:

#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 je l'ai expliqué correctement, cela devrait vous permettre d'avoir un bouton d'image d'arrière-plan qui s'estompe, j'espère que cela aide au moins!

Austin Parrish Thomas
la source
3
J'en ai également fait une version tutoriel vidéo. youtube.com/watch?v=6ieR5ApVpr0
Austin Parrish Thomas
Vous ne devriez pas, AFAIK, avoir besoin de spécifier les transitions sur la pseudo-classe de survol; la définition de transition pour le type de balise d'ancrage sera reportée au comportement de survol, tout ce que vous devez changer est l'opacité. Gardez à l'esprit que cet exemple fonctionne bien car les styles sont appliqués directement aux ID / types de balises; si vous faites cela avec des classes, vous devez vous assurer de ne pas ajouter et supprimer la classe avec la transition définie.
KeithS
15

Malheureusement, vous ne pouvez pas utiliser la transition background-image, voir la liste w3c des propriétés animables .

Vous voudrez peut-être faire quelques astuces avec background-position.

Olwaro
la source
13

Vous pouvez utiliser un pseudo élément pour obtenir l'effet souhaité, comme je l'ai fait dans ce 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
la source
2
Cela fonctionne très bien, mais vous pouvez rencontrer 2 problèmes: 1) si vous ne voyez pas l' :afterélément, essayez de définir widthet heightau 100%lieu de inherit, 2) si le background-imageest réellement affiché au premier plan , utilisez un index négatif pour l' :afterélément:z-index: -1;
Radek Pech
9

Si vous pouvez utiliser jQuery, vous pouvez essayer le plugin BgSwitcher pour changer l'image d'arrière-plan avec des effets, c'est très facile à utiliser.

Par exemple :

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

Et ajoutez votre propre effet, voir l' ajout d'un type d'effet

MaxDhn
la source
Merci, j'ai résolu le problème avec l'animation du changement d'arrière-plan de la table avec l'utilisation de ce plugin.
userlond
4

Essayez ceci, cela rendra l'arrière-plan animé fonctionnera sur le Web mais l'application mobile hybride ne fonctionnera pas

@-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
la source
4

Étant donné que les images d'arrière-plan ne peuvent pas être animées, j'ai créé un petit mixin SCSS permettant de faire la transition entre 2 images d'arrière-plan différentes à l'aide de pseudo sélecteurs avant et après . Ils se trouvent à différentes couches d'indice z. Celui qui est en avant commence par l'opacité 0 et devient visible avec le survol.

Vous pouvez également utiliser la même approche pour créer des animations avec des dégradés linéaires.

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; 
     }
  }  
}

Maintenant, vous pouvez simplement l'utiliser avec

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

Vous pouvez le vérifier ici: https://jsfiddle.net/pablosgpacheco/01rmg0qL/

Pablo SG Pacheco
la source
Très belle solution!
M'a permis de
3

Si l'animation opacityn'est pas une option, vous pouvez également animerbackground-size .

Par exemple, j'ai utilisé ce CSS pour définir un backgound-imageavec un délai.

.before {
  background-size: 0;
}

.after {
  transition: background 0.1s step-end;
  background-image: $path-to-image;
  background-size: 20px 20px;
}
shock_one
la source
Si vous voulez un effet de fondu de .afterdans .beforepour l'image d'arrière-plan, vous devez définir l'image d'arrière-plan dans le .before. Sinon, il disparaîtra simplement sans animation.
Radek Pech
2

Salam, cette réponse ne fonctionne que dans Chrome, car IE et FF prennent en charge la transition de couleur.

Il n'est pas nécessaire de créer vos éléments HTML opacity:0, car parfois ils contiennent du texte, et pas besoin de doubler vos éléments !.

La question lien vers un exemple dans jsFiddle avait besoin d' un petit changement, qui est de mettre une image vide .title acomme background:url(link to an empty image);même que vous le mettre en .title a:hovermais en faire l' image vide, et le code fonctionnera.

.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;
}

Vérifiez ceci https://jsfiddle.net/Tobasi/vv8q9hum/

Mohammed Suleiman
la source
Ne fonctionne toujours pas sur Fire Fox ou IE :(, mais semble bien en chrome
mohammed Suleiman
1

Avec le post inspirant de Chris ici:

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

J'ai réussi à trouver ceci:

#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
la source
0

Cela peut être réalisé avec une meilleure prise en charge de plusieurs navigateurs que la réponse acceptée en utilisant des pseudo-éléments comme illustré par cette réponse: https://stackoverflow.com/a/19818268/2602816

vaer-k
la source
0

Je me débattais un peu avec cela, j'ai d'abord utilisé une pile d'images les unes sur les autres et toutes les trois secondes, j'essayais d'animer jusqu'à l'image suivante de la pile et de jeter l'image actuelle au bas de la pile. En même temps, j'utilisais des animations comme indiqué ci-dessus. Je n'ai pas pu le faire fonctionner pour ma vie.

Vous pouvez utiliser cette bibliothèque qui permet ** une image d'arrière-plan redimensionnée dynamiquement, capable de diaporama ** en utilisant jquery-backstretch.

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

Akhil Khanna
la source