Animation CSS3: affichage + opacité

101

J'ai un problème avec une animation CSS3.

.child {
    opacity: 0;
    display: none;

    -webkit-transition: opacity 0.5s ease-in-out;
    -moz-transition: opacity 0.5s ease-in-out;
    transition: opacity 0.5s ease-in-out;
}

.parent:hover .child {
    opacity: 0.9;
    display: block;
}

Ce code ne fonctionne que si je supprime le changement de display.

Je souhaite changer l'affichage juste après le survol, mais l'opacité doit être modifiée à l'aide de la transition.

Alexis Delrieu
la source
2
Si CSS ne fonctionne pas comme les autres l'ont suggéré, voici un code Javascript très simple pour la décoloration.
Abhranil Das

Réponses:

118

Basé sur la réponse de Michaels, il s'agit du code CSS réel à utiliser

.parent:hover .child
{
    display: block;

    -webkit-animation: fadeInFromNone 0.5s ease-out;
    -moz-animation: fadeInFromNone 0.5s ease-out;
    -o-animation: fadeInFromNone 0.5s ease-out;
    animation: fadeInFromNone 0.5s ease-out;
}

@-webkit-keyframes fadeInFromNone {
    0% {
        display: none;
        opacity: 0;
    }

    1% {
        display: block;
        opacity: 0;
    }

    100% {
        display: block;
        opacity: 1;
    }
}

@-moz-keyframes fadeInFromNone {
    0% {
        display: none;
        opacity: 0;
    }

    1% {
        display: block;
        opacity: 0;
    }

    100% {
        display: block;
        opacity: 1;
    }
}

@-o-keyframes fadeInFromNone {
    0% {
        display: none;
        opacity: 0;
    }

    1% {
        display: block;
        opacity: 0;
    }

    100% {
        display: block;
        opacity: 1;
    }
}

@keyframes fadeInFromNone {
    0% {
        display: none;
        opacity: 0;
    }

    1% {
        display: block;
        opacity: 0;
    }

    100% {
        display: block;
        opacity: 1;
    }
}
Chris
la source
1
pour prendre en charge tous les navigateurs ..?
david_adler
CSS3 n'est pas pris en charge dans tous les navigateurs. Si vous voulez étendre, ajoutez simplement les préfixes corrects
Chris
17
Qu'en est-il lors du survol, comment implémenter fadeOutToNone?
Vert
4
Comme vous pouvez utiliser des fractions de pour cent, il est préférable d'utiliser quelque chose comme 0,001% plutôt que 1% car cela minimise le délai pour "démarrer", ce qui peut devenir apparent avec des durées d'animation plus longues
Zach Saucier
1
La directive -o-keyframes est en fait inutile car la première version d'Opera à prendre en charge les animations était déjà basée sur webkit.
Rico Ocepek
43

Vous pouvez faire avec des animations CSS:

0% display:none ; opacity: 0;
1% display: block ; opacity: 0;
100% display: block ; opacity: 1;
Michael Mullany
la source
Bonne idée, j'ai réussi à continuer d'afficher mon élément pendant le survol avec animation-fill-mode mais ensuite au curseur de la souris, l'élément disparaît.
Alexis Delrieu
2
vous pouvez utiliser fill-mode: forward pour conserver les modifications une fois l'animation terminée.
Michael Mullany
42

Si possible, utilisez à la visibilityplace dedisplay

Par exemple:

.child {
    visibility: hidden;
    opacity: 0;
    transition: opacity 0.3s, visibility 0.3s;
}

.parent:hover .child {
    visibility: visible;
    opacity: 1;
    transition: opacity 0.3s, visibility 0.3s;
}
tomas.satinsky
la source
24
Le problème avec la propriété de visibilité est que cela ne masque pas l'élément, cela le rend seulement invisible. Cela prendra donc encore de la place.
Samuel
6
Non seulement invisible, mais également transparent aux événements (clics, etc.). Ne pas changer d'affichage signifie ne pas redéfinir le document, ce qui est une bonne chose. La plupart des éléments qui devraient apparaître / disparaître par opacité devraient probablement avoir une position fixe ou absolue de toute façon.
Rasmus Kaj
13

Cette solution de contournement fonctionne:

  1. définir une «image clé»:

    @-webkit-keyframes fadeIn { 
      0% { opacity: 0; }
      20% { opacity: 0; }
      40% { opacity: 0.3; }
      60% { opacity: 0.5; }
      80% { opacity: 0.9; }
      100% { opacity: 1; }
    }
    
    @keyframes fadeIn {
      0% { opacity: 0; }
      20% { opacity: 0; }
      40% { opacity: 0.3; }
      60% { opacity: 0.5; }
      80% { opacity: 0.9; }
      100% { opacity: 1; }
    }
    
  2. Utilisez cette «image clé» en «survol»:

    div a span { 
      display: none;
    }
    
    div a:hover span {
      display: block;
    
      -webkit-animation-name: fadeIn;
      -webkit-animation-duration: 1s;
      animation-name: fadeIn;
      animation-duration: 1s;
    }
    
Hermann Schwarz
la source
9

J'ai utilisé cela pour y parvenir. Ils s'estompent en vol stationnaire mais ne prennent pas de place lorsqu'ils sont cachés, parfait!

.child {
    height: 0px;
    opacity: 0;
    visibility: hidden;
    transition: all .5s ease-in-out;
}

.parent:hover .child {
    height: auto;
    opacity: 1;
    visibility: visible;
}
Felixhirschfeld
la source
6

J'ai un peu changé mais le résultat est magnifique.

.child {
    width: 0px;
    height: 0px;
    opacity: 0;
}

.parent:hover child {
    width: 150px;
    height: 300px;
    opacity: .9;
}

Merci tout le monde.

Alexis Delrieu
la source
4
Cela ne fonctionne pas bien avec les lecteurs d'écran: ils continueront à lire le contenu.
ehdv
1
Vous pouvez ajouter visibility: hidden;à .child / au survol visibility:visible;et cela devrait résoudre le problème du lecteur d'écran
csilk
6

Il existe une autre bonne méthode pour y parvenir en utilisant des événements de pointeur:

.child {
    opacity: 0;
    pointer-events: none;

    -webkit-transition: opacity 0.5s ease-in-out;
    -moz-transition: opacity 0.5s ease-in-out;
    transition: opacity 0.5s ease-in-out;
}

.parent:hover .child {
    opacity: 0.9;
    pointer-events: all;
}

Malheureusement, cela n'est pas pris en charge dans IE10 et les versions antérieures.

RafaelKr
la source
4

J'ai eu le même problème. J'ai essayé d'utiliser des animations au lieu de transitions - comme suggéré par @MichaelMullany et @Chris - mais cela ne fonctionnait que pour les navigateurs webkit même si je copiais-collé avec les préfixes "-moz" et "-o".

J'ai pu contourner le problème en utilisant visibilityau lieu de display. Cela fonctionne pour moi car mon élément enfant l'est position: absolute, donc le flux de documents n'est pas affecté. Cela pourrait aussi fonctionner pour d'autres.

Voici à quoi ressemblerait le code d'origine en utilisant ma solution:

.child {
    position: absolute;
    opacity: 0;
    visibility: hidden;

    -webkit-transition: opacity 0.5s ease-in-out;
    -moz-transition: opacity 0.5s ease-in-out;
    transition: opacity 0.5s ease-in-out;
}

.parent:hover .child {
    position: relative;
    opacity: 0.9;
    visibility: visible;
}
Dave
la source
Si vous reveniez sur l'enfant pendant son animation hors de vue, il se réenclencherait puisque l'élément est simplement caché. Assez ennuyeux si vous déplacez votre souris autour de l'endroit.
adamj
4

Si vous déclenchez le changement avec JS, disons en cliquant, il existe une belle solution de contournement.

Vous voyez que le problème se produit parce que l'animation est ignorée à l'affichage: aucun élément mais le navigateur applique toutes les modifications à la fois et l'élément n'est jamais affiché: bloc tant qu'il n'est pas animé en même temps.

L'astuce consiste à demander au navigateur de rendre l'image après avoir changé la visibilité mais avant de déclencher l'animation.

Voici un exemple JQuery:

    $('.child').css({"display":"block"});
    //now ask the browser what is the value of the display property
    $('.child').css("display"); //this will trigger the browser to apply the change. this costs one frame render
    //now a change to opacity will trigger the animation
    $('.child').css("opacity":100);
daniel.sedlacek
la source
2
Cette question n'est marquée ni avec JavaScript ni avec jQuery
j08691
Je sais, je l'ai écrit pour expliquer la raison pour laquelle cela se produit. Cela m'a été très utile lorsque j'ai appris cela et j'espère que cela aidera les autres aussi.
daniel.sedlacek
1
Btw, les valeurs d'opacité sont comprises entre 0 et 1
Amr
2

Sur les éléments absolus ou fixes, vous pouvez également utiliser z-index:

.item {
    position: absolute;
    z-index: -100;
}

.item:hover {
    z-index: 100;
}

Les autres éléments devraient avoir un z-index entre -100 et 100 maintenant.

Luca Steeb
la source
Malheureusement, cela bousille le symbole d'indicateur de mot de passe KeePass sur les type=passwordchamps. Ce n'est pas visible.
philk
1
Pouvons-nous arrêter d'utiliser des nombres d'index z arbitraires? Ici: z-index: 1; vs z-index: -1 fera très bien l'affaire. Choisir d'énormes nombres d'index z rend les choses ingérables.
dudewad
2

Je sais, ce n'est pas vraiment une solution à votre question, car vous demandez

affichage + opacité

Mon approche résout une question plus générale, mais c'est peut-être le problème d'arrière-plan qui devrait être résolu en utilisant displayen combinaison avec opacity.

Mon désir était d'éloigner l'élément lorsqu'il n'est pas visible. Cette solution fait exactement cela: elle déplace l'élément hors de l'extérieur, et cela peut être utilisé pour la transition:

.child {
  left: -2000px;
  opacity: 0;
  visibility: hidden;
  transition: left 0s 0.8s, visibility 0s 0.8s, opacity 0.8s;
}

.parent:hover .child {
  left: 0;
  opacity: 1;
  visibility: visible;
  transition: left 0s, visibility 0s, opacity 0.8s;
}

Ce code ne contient aucun préfixe de navigateur ou hacks de compatibilité descendante. Il illustre simplement le concept de la façon dont l'élément est éloigné car il n'est plus nécessaire.

La partie intéressante sont les deux définitions de transition différentes. Lorsque le pointeur de la souris survole l' .parentélément, l' .childélément doit être mis en place immédiatement, puis l'opacité sera modifiée:

transition: left 0s, visibility 0s, opacity 0.8s;

Lorsqu'il n'y a pas de survol ou que le pointeur de la souris a été déplacé de l'élément, il faut attendre que le changement d'opacité soit terminé avant que l'élément puisse être déplacé hors de l'écran:

transition: left 0s 0.8s, visibility 0s 0.8s, opacity 0.8s;

Éloigner l'objet sera une alternative viable dans le cas où le réglage display:nonene casserait pas la mise en page.

J'espère avoir frappé dans le mille pour cette question même si je n'y ai pas répondu.

Hannes Morgenstern
la source
Ce filtre Microsoft est obsolète depuis IE9. Une raison particulière pour laquelle vous avez envie de l'ajouter aux réponses en 2016?
TylerH
@TylerH Le nombre d'utilisateurs que l'on veut atteindre est une question de goût.
Hannes Morgenstern
Étant donné qu'il est obsolète et que IE <11 n'est plus pris en charge par Microsoft, l'utilisation de cette propriété est alors au mieux d'un goût douteux.
TylerH
@TylerH Il est courant de devoir accueillir des clients qui ne vont pas ou ne peuvent pas passer à un navigateur plus récent. J'ai une banque bien connue en tant que client qui utilise toujours IE6 et refuse de mettre à niveau pour des «raisons».
Marcus Cunningham
@MarcusCunningham La question est balisée avec css3, ce qui exclut totalement l'utilisation d'IE6 (et d'IE7 et d'IE8). Dans le premier navigateur possible, OP aurait pu écrire du code pour, le filtre MS de cette réponse était obsolète. Et pour les futurs lecteurs, c'est encore plus inutile car il n'est même pas pris en charge. Il n'y a aucun argument pour l'inclure dans une réponse à cette question. C'est un point discutable, cependant, puisque Hannes l'a déjà retiré de sa réponse.
TylerH
1

Une chose que j'ai faite a été de définir la marge de l'état initial comme étant quelque chose comme "margin-left: -9999px" afin qu'elle n'apparaisse pas à l'écran, puis réinitialiser "margin-left: 0" sur l'état de survol. Gardez-le "display: block" dans ce cas. A fait l'affaire pour moi :)

Modifier: enregistrer l'état et ne pas revenir à l'état de survol précédent? Ok ici, nous avons besoin de JS:

<style>
.hovered { 
    /* hover styles here */
}
</style>

<script type="text/javascript">
$('.link').hover(function() {
   var $link = $(this);
   if (!$link.hasclass('hovered')) { // check to see if the class was already given
        $(this).addClass('hovered');
   } 
});
</script>
Joshua
la source
Bonne idée, mais ensuite je souris, l'élément disparaît…
Alexis Delrieu
Alexis, n'est-ce pas ce que tu veux faire? Hover signifie UNIQUEMENT lorsque vous survolez avec votre souris. Veuillez clarifier ce que vous essayez d'accomplir.
Joshua
Oui désolé. Je veux enregistrer le fondu dans la sortie de la souris.
Alexis Delrieu
Cela change tout. Presque. Fondamentalement, ce que vous voulez, c'est une fonction JS qui détectera l'état de survol, comme d'autres utilisateurs l'ont indiqué, et ajoutera ... eh bien ... voir ma réponse mise à jour.
Joshua
1

Pour avoir une animation dans les deux sens onHoverIn / Out, j'ai fait cette solution. J'espère que cela aidera quelqu'un

@keyframes fadeOutFromBlock {
  0% {
    position: relative;
    opacity: 1;
    transform: translateX(0);
  }

  90% {
    position: relative;
    opacity: 0;
    transform: translateX(0);
  }

  100% {
    position: absolute;
    opacity: 0;
    transform: translateX(-999px);
  }
}

@keyframes fadeInFromNone {
  0% {
    position: absolute;
    opacity: 0;
    transform: translateX(-999px);
  }

  1% {
    position: relative;
    opacity: 0;
    transform: translateX(0);
  }

  100% {
    position: relative;
    opacity: 1;
    transform: translateX(0);
  }
}

.drafts-content {
  position: relative;
  opacity: 1;
  transform: translateX(0);
  animation: fadeInFromNone 1s ease-in;
  will-change: opacity, transform;

  &.hide-drafts {
    position: absolute;
    opacity: 0;
    transform: translateX(-999px);
    animation: fadeOutFromBlock 0.5s ease-out;
    will-change: opacity, transform;
  }
}
Nicolas
la source
0

COMMENT ANIMER L'OPACITÉ AVEC CSS: voici
mon code:
le code CSS

.item {   
    height:200px;
    width:200px;
    background:red;
    opacity:0;
    transition: opacity 1s ease-in-out;
}

.item:hover {
    opacity: 1;
}
code {
    background: linear-gradient(to right,#fce4ed,#ffe8cc);
}
<div class="item">

</div>
<p><code> move mouse over top of this text</code></p>

ou consultez ce fichier de démonstration

function vote () {
var vote = getElementById ("yourOpinion")
if (this.workWithYou):
vote + = 1};
lol

zakizakibzr
la source
1
Ne répond pas à la question, car la displaypropriété a simplement été supprimée.
Toast le
-4

display:n'est pas transposable. Vous devrez probablement utiliser jQuery pour faire ce que vous voulez faire.

Fantôme de Madara
la source
3
Vous devez arrêter de préconiser jQuery partout mec.
Benjamin Gruenbaum
1
@BenjaminGruenbaum jQuery est un homme incroyable. C'est génial et fait tout.
Madara's Ghost