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.


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

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;

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

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

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

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.


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.


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

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

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.


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.


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>

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

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


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.


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.