Transitions sur la propriété d'affichage CSS

1449

Je suis en train de concevoir un «menu déroulant» CSS - essentiellement un menu déroulant CSS uniquement, mais qui contient différents types de contenu.

Pour le moment, il semble que les transitions CSS 3 ne s'appliquent pas à la propriété 'display' , c'est-à-dire que vous ne pouvez faire aucune sorte de transition de display: noneà display: block(ou toute combinaison).

Existe-t-il un moyen pour le menu de deuxième niveau de l'exemple ci-dessus de 'fondre' quand quelqu'un survole l'un des éléments de menu de niveau supérieur?

Je sais que vous pouvez utiliser des transitions sur la visibility:propriété, mais je ne peux pas penser à un moyen de l'utiliser efficacement.

J'ai également essayé d'utiliser la hauteur, mais cela a échoué lamentablement.

Je suis également conscient qu'il est trivial d'y parvenir en utilisant JavaScript, mais je voulais me mettre au défi d'utiliser uniquement CSS, et je pense que je viens un peu court.

RichardTape
la source
La transition CSS fonctionne-t-elle si vous l'appliquez à la propriété d'opacité, plutôt que de l'afficher?
Paul D. Waite
13
position: absolue; visibilité: caché; est identique à l'affichage: aucun;
Jawad
8
@Jawad: Seulement si vous ajoutez quelque chose comme ça z-index:0aussi.
DanMan
7
@Jawad: Il est recommandé de ne jamais l'utiliser visibility: hiddensauf si vous souhaitez que les lecteurs d'écran le lisent (contrairement aux navigateurs classiques). Il ne définit que la visibilité de l'élément (comme dire opacity: 0), et il est toujours sélectionnable, cliquable et quoi qu'il soit; ce n'est tout simplement pas visible.
Forest Katsch
1
pas de prise pointer-eventsen charge dans IE 8,9,10, donc ce n'est pas toujours correct
Steven Pribilinskiy

Réponses:

1352

Vous pouvez concaténer deux transitions ou plus, et visibilityc'est ce qui est utile cette fois.

div {
  border: 1px solid #eee;
}
div > ul {
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s, opacity 0.5s linear;
}
div:hover > ul {
  visibility: visible;
  opacity: 1;
}
<div>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>
</div>

(N'oubliez pas les préfixes du vendeur à la transitionpropriété.)

Plus de détails sont dans cet article .

Guillermo
la source
10
Cette réponse semble être moins de travail que les autres et atteint ce que nous attendons de l'affichage: aucun / bloc; Merci. Cela m'a fait gagner une tonne de temps.
Brendan
21
Oui, le problème est que tout ce qui se cache derrière se chevauchera même s'il n'est pas visible. J'ai trouvé que l'utilisation de height: 0 était une bien meilleure solution
Josh Bedo
742
C'est bien, mais le problème est que les éléments "visibilité cachée" occupent toujours de l'espace alors que "afficher aucun" ne l'est pas.
Rui Marques
41
Il me manque probablement quelque chose, mais pourquoi modifiez-vous à la fois la visibilité ET l'opacité? Ne définira pas l'opacité à 0 pour masquer l'élément - pourquoi devez-vous également définir la visibilité sur masqué?
GMA
21
@GeorgeMillo si vous définissez uniquement l'opacité, l'élément est en fait toujours sur le rendu de la page (vous ne pouvez pas cliquer sur pensée par exemple).
adriendenat
801

Vous devez masquer l'élément par d'autres moyens pour que cela fonctionne.

J'ai accompli l'effet en positionnant les deux <div>absolument et en réglant le caché sur opacity: 0.

Si vous basculez même la displaypropriété de nonelablock , votre transition sur d'autres éléments ne se produira pas.

Pour contourner ce problème, laissez toujours l'élément être display: block, mais masquez-le en ajustant l'un de ces moyens:

  1. Réglez heightsur 0.
  2. Réglez opacitysur 0.
  3. Positionnez l'élément en dehors du cadre d'un autre élément qui a overflow: hidden.

Il existe probablement plus de solutions, mais vous ne pouvez pas effectuer de transition si vous basculez l'élément vers display: none. Par exemple, vous pouvez essayer d'essayer quelque chose comme ceci:

div {
    display: none;
    transition: opacity 1s ease-out;
    opacity: 0;
}
div.active {
    opacity: 1;
    display: block;
}

Mais cela ne fonctionnera pas . D'après mon expérience, j'ai trouvé que cela ne faisait rien.

Pour cette raison, vous devrez toujours conserver l'élément display: block- mais vous pouvez le contourner en faisant quelque chose comme ceci:

div {
    transition: opacity 1s ease-out;
    opacity: 0;
    height: 0;
    overflow: hidden;
}
div.active {
    opacity: 1;
    height: auto;
}
Jim Jeffers
la source
29
Merci Jim pour une réponse complète. Vous avez absolument raison de dire que si l'affichage: la propriété change, alors TOUTES vos transitions ne fonctionneront pas. Ce qui est dommage - je me demande quel est le raisonnement derrière cela. En passant, sur le même lien que j'ai posté dans la question d'origine, vous pouvez voir où j'en suis avec. Le seul (petit) problème que j'ai est dans Chrome [5.0.375.125] lorsque la page se charge, vous pouvez voir le menu disparaître rapidement lorsque les éléments sont chargés sur la page. Firefox 4.0b2 et Safari 5.0 sont tout à fait correct ... bug ou quelque chose que j'ai manqué?
RichardTape
7
Je suis d'accord pour dire que c'est exact et que j'y contribuerai; un en tête pour les futurs voyageurs. J'ai trouvé une solution qui fonctionne dans Chrome, mais j'ai trouvé qu'elle échoue sur iPhone 4: visibility:hidden; opacity:0; -webkit-transition: all .2s ease-in-out;Non seulement cela ne se transforme pas correctement, mais l'élément cible ne s'affichera jamais. QA vous fera défaut, moi et votre maman.
SimplGy
1
Vous pouvez également faire la transition de la propriété de visibilité .. juste en disant
Cu7l4ss
2
Si vous définissez votre état masqué sur height: 0;et ne le transformez pas, la transition ne fonctionnera pas. J'ai essayé cela simplement en essayant de faire la transition de l'opacité. J'ai dû retirer leheight: 0;
chovy
10
vous venez de gagner un vote grâce au overflow: hiddenmerci beaucoup!
thiagoh
279

Au moment de cette publication, tous les principaux navigateurs désactivent les transitions CSS si vous essayez de modifier la displaypropriété, mais les animations CSS fonctionnent toujours bien afin que nous puissions les utiliser comme solution de contournement.

Exemple de code (vous pouvez l'appliquer à votre menu en conséquence) Démo :

Ajoutez le CSS suivant à votre feuille de style:

@-webkit-keyframes fadeIn {
    from { opacity: 0; }
      to { opacity: 1; }
}
@keyframes fadeIn {
    from { opacity: 0; }
      to { opacity: 1; }
}

Ensuite, appliquez l' fadeInanimation à l'enfant lors du survol des parents (et bien sûr défini display: block):

.parent:hover .child {
    display: block;
    -webkit-animation: fadeIn 1s;
    animation: fadeIn 1s;
}

Mise à jour 2019 - Méthode qui prend également en charge la décoloration:

(Un code JavaScript est requis)

// We need to keep track of faded in elements so we can apply fade out later in CSS
document.addEventListener('animationstart', function (e) {
  if (e.animationName === 'fade-in') {
      e.target.classList.add('did-fade-in');
  }
});

document.addEventListener('animationend', function (e) {
  if (e.animationName === 'fade-out') {
      e.target.classList.remove('did-fade-in');
   }
});
div {
    border: 5px solid;
    padding: 10px;
}

div:hover {
    border-color: red;
}

.parent .child {
  display: none;
}

.parent:hover .child {
  display: block;
  animation: fade-in 1s;
}

.parent:not(:hover) .child.did-fade-in {
  display: block;
  animation: fade-out 1s;
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fade-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
<div class="parent">
    Parent
    <div class="child">
        Child
    </div>
</div>

Salman von Abbas
la source
3
Merci pour cela. L' height: 0astuce (pour les transitions) mentionnée ci-dessus ne semble pas fonctionner car la hauteur est définie sur 0 lors de la transition en fondu, mais cette astuce semble fonctionner très bien.
Elliot Winkler
41
Merci, très utile. Mais comment le faire disparaître?
Illiou
1
Le premier paragraphe de cette réponse n'a pas vraiment de sens. Les navigateurs ne désactivent pas simplement toutes les transitions au moment où vous utilisez la displaypropriété - il n'y a vraiment aucune raison de le faire. Et même s'ils le faisaient , pourquoi les animations fonctionneraient-elles alors? Vous ne pouvez pas non plus utiliser la displaypropriété dans les animations CSS.
BoltClock
7
Meilleure réponse, pas possible avec des transitions mais oui avec des animations.
Mikel
6
Que diriez-vous de l'animation inverse, c'est-à-dire que l'élément devrait disparaître lentement?
Vert
77

Je soupçonne que la raison pour laquelle les transitions sont désactivées si elles displaysont modifiées est à cause de ce que fait réellement l'affichage. Il ne ne change rien qui pourrait peut - être animé en douceur.

display: none;et visibility: hidden;sont deux choses entièrement différentes.
Les deux ont pour effet de rendre l'élément invisible, mais avec visibility: hidden;son rendu dans la mise en page, mais tout simplement pas visiblement .
L'élément caché occupe toujours de l'espace et est toujours rendu en ligne ou en tant que bloc ou bloc en ligne ou table ou tout ce que l' displayélément lui dit de rendre en tant que, et prend de l'espace en conséquence.
D'autres éléments ne se déplacent pas automatiquement pour occuper cet espace. L'élément caché ne rend tout simplement pas ses pixels réels à la sortie.

display: noned'autre part en fait empêche l'élément de rendu entièrement .
Il ne prend aucun espace de mise en page.
D'autres éléments qui auraient occupé une partie ou la totalité de l'espace occupé par cet élément s'ajustent maintenant pour occuper cet espace, comme si l'élément n'existait tout simplement pas .

displayn'est pas simplement un autre attribut visuel.
Il établit le mode entier rendu de l'élément, par exemple , que ce soit un block, inline, inline-block, table, table-row, table-cell, list-item, ou quoi que!
Chacun de ceux -ci ont très différentes ramifications de mise en page, et il n'y aurait aucun moyen raisonnable d'encourager ou en douceur les transition (essayez d'imaginer une transition en douceur de blocklainline ou vice-versa, par exemple!).

C'est pourquoi les transitions sont désactivées si l'affichage change (même si le changement est de ou vers none- nonen'est pas simplement l'invisibilité, c'est son propre mode de rendu d'élément qui signifie aucun rendu du tout!).

Joel_MMCC
la source
8
Aussi bonnes que puissent être les solutions ci-dessus, il était très satisfaisant d'obtenir une explication raisonnable quant aux raisons pour lesquelles les transitions ne s'appliquent pas aux attributs d'affichage.
kqr
8
Je ne suis pas d'accord. Cela pourrait avoir tout son sens. Si affichage: aucun à afficher: le blocage s'est produit instantanément au début de la transition, ce serait formidable. Et pour la transition en arrière, si cela passait de display: block à display: aucun à la fin de la transition, ce serait parfait.
Curtis Yallop
2
Si vous ne pouvez pas imaginer à quoi ressemble une animation d'un point à un rectangle, vous avez des problèmes. Une transition de l'occupation d'aucun espace à l'occupation d'un espace rectangulaire est TRÈS évidente, comme, vous le faites chaque fois que vous faites glisser un rectangle avec la souris comme chaque application. À la suite de cet échec, il y a tellement de hacks impliquant la hauteur maximale et les marges négatives que c'est ridicule. La seule chose qui fonctionne est la mise en cache de la hauteur «réelle», puis l'animation de zéro à la valeur mise en cache avec JavaScript. Triste.
Triynko
2
Tryniko: affichage: aucun ne change pas la taille de l'élément en un rectangle de 0 x 0 - il le supprime du DOM. Vous pouvez animer d'un rectangle à un point en animant les propriétés de largeur et de hauteur à zéro, puis les autres éléments circuleraient comme s'il avait 'display: none' mais son attribut 'display' resterait 'block'; l'élément est toujours dans le DOM. Le concept d'animation entre affichage: bloc et affichage: aucun n'est ridicule: il n'y a pas d'états intermédiaires. Un élément existe soit dans le DOM, soit il n'existe pas, qu'il soit petit ou invisible.
Steve Thorpe
1
Il n'est pas ridicule d'animer des propriétés discrètes. Les propriétés discrètes comme displayne peuvent pas être transférées en douceur comme les autres propriétés, mais cela ne signifie pas que le timing n'est pas important. Être capable de contrôler quand la transition de disply:blockse display:noneproduit est très important. Tout comme @CurtisYallop l'a décrit. Si je veux faire la transition entre opacity:1la opacity:0et puis le changement display:blockde display:noneje devrais être en mesure de le faire.
Jens
57

Au lieu de rappels, qui n'existent pas en CSS, nous pouvons utiliser la transition-delaypropriété.

#selector {
    overflow: hidden; // Hide the element content, while height = 0
    height: 0; opacity: 0;
    transition: height 0ms 400ms, opacity 400ms 0ms;
}
#selector.visible {
    height: auto; opacity: 1;
    transition: height 0ms 0ms, opacity 600ms 0ms;
}

Alors, que se passe-t-il ici?

  1. Lorsque la visibleclasse est ajoutée, les deux heightet opacitydémarrent l'animation sans délai (0 ms), mais cela heightprend 0 ms pour terminer l'animation (équivalent de display: block) et opacityprend 600 ms.

  2. Lorsque la visibleclasse est supprimée, opacitydémarre l'animation (délai de 0 ms, durée de 400 ms) et la hauteur attend 400 ms, puis seulement instantanément (0 ms) restaure la valeur initiale (équivalente à display: nonedans le rappel d'animation).

Notez que cette approche est meilleure que celles utilisées visibility. Dans de tels cas, l'élément occupe toujours l'espace sur la page, et il n'est pas toujours adapté.

Pour plus d'exemples, veuillez vous référer à cet article .

Webars
la source
8
surpris que cela n'ait pas plus de votes positifs - cette solution intelligente fonctionne en quelque sorte parfaitement.
fanfare le
3
Il ne fonctionne qu'avec height:100%qui peut détruire la mise en page dans certains cas. Excellente solution, si ce n'est pas un problème. L'un des rares fonctionnants bidirectionnels.
Fabian von Ellerts
C'est bien! J'ai pu le simplifier encore plus dans mon cas car je voulais que le temps d'animation de fondu soit le même que le temps de fondu d'entrée. Plutôt que d'utiliser transition: height 0ms 0ms, opacity 600ms 0ms, je viens de l'utiliser transition-delay: 0s.
Jacob Lockard
52

display ne fait pas partie des propriétés sur lesquelles opère la transition.

Voir Propriétés CSS animables pour la liste des propriétés CSS qui peuvent avoir des transitions qui leur sont appliquées. Voir Module de valeurs et d'unités CSS, niveau 4, Combinaison de valeurs: interpolation, addition et accumulation pour savoir comment elles sont interpolées.

Jusqu'à CSS 3 était répertorié en 9.1. Propriétés de CSS (fermez simplement la fenêtre d'avertissement)

J'ai également essayé d'utiliser la hauteur, mais cela a échoué lamentablement.

La dernière fois que j'ai dû le faire, j'ai utilisé à la max-heightplace, qui est une propriété animable (même si c'était un peu un hack, cela a fonctionné), mais attention, cela peut être très saccadé pour les pages complexes ou les utilisateurs avec un mobile bas de gamme dispositifs.

robocat
la source
Le lien ne pointe plus directement vers la section des propriétés animables.
Andrew Lam
1
@AndrewLam Fixed. Merci.
robocat
34

Vous pouvez maintenant ajouter une animation personnalisée à la propriété de bloc.

@keyframes showNav {
  from {opacity: 0;}
  to {opacity: 1;}
}
.subnav-is-opened .main-nav__secondary-nav {
  display: block;
  animation: showNav 250ms ease-in-out both;
}

Démo

Dans cette démo, le sous-menu passe de display:noneà display:blocket parvient toujours à s'estomper.

Manish Pradhan
la source
Doit myfirstêtre showNavici? Et qu'en est-il de Firefox? Malheureusement, je ne trouve rien sur la page de démonstration que vous mentionnez.
Sebastian vom Meer
Merci @SebastianG. J'ai fait la correction et ajouté plus d'informations ci-dessus.
Manish Pradhan
@Sebastian vom Meer: les anciennes versions de Firefox nécessitent le préfixe "-moz-", voir le code édité
Herr_Schwabullek
23
À moins que je manque quelque chose, le lien "démo" n'affiche plus de transition de sous-menu.
Réaliste
1
La transition correcte pour quelque chose qui n'occupe pas d'espace (comme c'est le cas avec display: none) vers quelque chose qui occupe de l'espace (display: block), est une expansion des dimensions, pas un fondu. S'il s'agissait d'une question de visibilité cachée (qui occupe de l'espace mais n'est pas visible) à visible, alors la taille reste la même et un fondu d'entrée est approprié. Aucune de ces réponses ne résout le problème.
Triynko
21

Selon le W3C Working Draft, le 19 novembre 2013 display n'est pas une propriété animable . Heureusement, visibilityest animable. Vous pouvez enchaîner sa transition avec une transition d'opacité ( JSFiddle ):

  • HTML:

    <a href="http://example.com" id="foo">Foo</a>
    <button id="hide-button">Hide</button>
    <button id="show-button">Show</button>
  • CSS:

    #foo {
        transition-property: visibility, opacity;
        transition-duration: 0s, 1s;
    }
    
    #foo.hidden {
        opacity: 0;
        visibility: hidden;
        transition-property: opacity, visibility;
        transition-duration: 1s, 0s;
        transition-delay: 0s, 1s;
    }
  • JavaScript pour les tests:

    var foo = document.getElementById('foo');
    
    document.getElementById('hide-button').onclick = function () {
        foo.className = 'hidden';
    };
    
    document.getElementById('show-button').onclick = function () {
        foo.className = '';
    };

Notez que si vous rendez le lien transparent, sans le définir visibility: hidden, il restera cliquable.

feklee
la source
1
je ne vois aucune transition du tout dans l'exemple jsfiddle
Gino
@Gino Je l'ai corrigé en changeant 0pour 0s. Apparemment, dans le passé, le navigateur que j'avais utilisé pour tester les temps zéro sans unité pris en charge. Cependant, les temps sans unité ne font pas partie de la recommandation du W3C du 29 septembre 2016 .
feklee
Cela devrait être davantage voté. J'ai trouvé que c'était l'une des meilleures solutions.
Arthur Tarasov
L'utilisation du délai est la meilleure logique pour comprendre comment cela fonctionne. Animez et cachez. Afficher et animer. Solution parfaite pour moi
Bruno Pitteli Gonçalves
15

Modifier: aucun affichage n'est appliqué dans cet exemple.

@keyframes hide {
  0% {
    display: block;
    opacity: 1;
  }
  99% {
    display: block;
  }
  100% {
    display: none;
    opacity: 0;
  }
}

Ce qui se passe ci-dessus, c'est que 99% de l'affichage de l'animation est réglé pour se bloquer pendant que l'opacité s'estompe. Au dernier moment, la propriété d'affichage est définie sur aucune.

Et le plus important est de conserver la dernière image après la fin de l'animation en utilisant animation-fill-mode: forwards

.hide {
   animation: hide 1s linear;
   animation-fill-mode: forwards;
}

Voici deux exemples: https://jsfiddle.net/qwnz9tqg/3/

Pawel
la source
avec cette solution display: nonene fonctionne pas alors?
Bart Calixto
Devrait être «animation-fill-mode: forwards» et non «forward»
Alex
Les modifications doivent être de six caractères et je ne peux que suggérer de modifier d'où le commentaire
Alex
1
@Alex Ok. Typo fixed. Ce qui est intéressant, c'est que ma réponse ne fonctionne même pas comme prévu, mais il est logique de penser que ce serait le cas, donc je la garderai jusqu'à ce que les navigateurs la prennent en charge.
Pawel
3
Comme vous pouvez le voir dans ce violon avec le jeu de curseurs,, display: nonen'est jamais réellement implémenté. jsfiddle.net/3e6sduqh
robstarbuck
14

Mon astuce JavaScript est de séparer le scénario entier en deux fonctions différentes !

Pour préparer les choses, une variable globale est déclarée et un gestionnaire d'événements est défini:

  var tTimeout;
  element.addEventListener("transitionend", afterTransition, true);//firefox
  element.addEventListener("webkitTransitionEnd", afterTransition, true);//chrome

Ensuite, lorsque je cache un élément, j'utilise quelque chose comme ceci:

function hide(){
  element.style.opacity = 0;
}

function afterTransition(){
  element.style.display = 'none';
}

Pour réapparaître l'élément, je fais quelque chose comme ceci:

function show(){
  element.style.display = 'block';
  tTimeout = setTimeout(timeoutShow, 100);
}

function timeoutShow(){
  element.style.opacity = 1;
}

Cela fonctionne, jusqu'à présent!

Sasa Milenkovic
la source
Cela fonctionne à cause du délai et non pas parce que les commandes javascript sont dans des fonctions séparées. Les retards semblent être une bonne solution dans de nombreux cas :)
10

Je suis tombé sur cela aujourd'hui, avec un position: fixedmodal que je réutilisais. Je ne pouvais pas le garder display: none, puis l'animer, car il venait juste d'apparaître et et z-index(valeurs négatives, etc.) faisait aussi des choses étranges.

J'utilisais également un height: 0to height: 100%, mais cela n'a fonctionné que lorsque le modal est apparu. C'est la même chose que si vous avez utilisé left: -100%ou quelque chose.

Ensuite, il m'a frappé qu'il y avait une réponse simple. Et voilà:

Tout d'abord, votre modal caché. Remarquez le heightest 0, et consultez la heightdéclaration dans les transitions ... elle a un 500ms, qui est plus long que ma opacitytransition . N'oubliez pas que cela affecte la transition de fondu sortant: le retour du modal à son état par défaut.

#modal-overlay {
    background: #999;
    background: rgba(33,33,33,.2);
    display: block;
    overflow: hidden;
    height: 0;
    width: 100%;
    position: fixed;
    top: 0;
    left: 0;
    opacity: 0;
    z-index: 1;
    -webkit-transition: height 0s 500ms, opacity 300ms ease-in-out;
       -moz-transition: height 0s 500ms, opacity 300ms ease-in-out;
            -ms-transition: height 0s 500ms, opacity 300ms ease-in-out;
         -o-transition: height 0s 500ms, opacity 300ms ease-in-out;
        transition: height 0s 500ms, opacity 300ms ease-in-out;
}

Deuxièmement, votre modal visible. Supposons que vous définissez a .modal-activesur body. Maintenant , heightc'est le cas 100%, et ma transition a également changé. Je veux que cela heightsoit changé instantanément et que ça opacityprenne 300ms.

.modal-active #modal-overlay {
    height: 100%;
    opacity: 1;
    z-index: 90000;
    -webkit-transition: height 0s, opacity 300ms ease-in-out;
       -moz-transition: height 0s, opacity 300ms ease-in-out;
        -ms-transition: height 0s, opacity 300ms ease-in-out;
         -o-transition: height 0s, opacity 300ms ease-in-out;
            transition: height 0s, opacity 300ms ease-in-out;
}

Ça y est, ça marche comme un charme.

hotmeteor
la source
Vote en faveur de votre style d'alignement des propriétés préfixées du vendeur 👍
George Green
9

En prenant quelques-unes de ces réponses et quelques suggestions ailleurs, ce qui suit fonctionne très bien pour les menus de survol (j'utilise cela avec Bootstrap  3, en particulier):

nav .dropdown-menu {
    display: block;
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    transition: max-height 500ms, opacity 300ms;
    -webkit-transition: max-height 500ms, opacity 300ms;
}
nav .dropdown:hover .dropdown-menu {
    max-height: 500px;
    opacity: 1;
    transition: max-height 0, opacity 300ms;
    -webkit-transition: max-height 0, opacity 300ms;
}

Vous pouvez également utiliser heightà la place de max-heightsi vous spécifiez les deux valeurs car cela height:auton'est pas autorisé avec transitions. La valeur de survol de max-heightdoit être supérieure à celle heightdu menu.

Edyn
la source
3
C'est une bonne astuce mais il y a une lacune. Le temps de transition dépend de la hauteur. S'il y a plusieurs menus avec une hauteur variable, ces éléments avec une hauteur plus proche de la hauteur maximale s'animeraient bien. Cependant, les plus courts s'animeraient trop vite, donnant une expérience incohérente.
utilisateur
8

J'ai trouvé un meilleur moyen pour ce problème, vous pouvez utiliser l'animation CSS et créer un effet impressionnant pour afficher les éléments.

    .item {
     display: none;
}

.item:hover {
     display: block;
     animation: fade_in_show 0.5s
}

@keyframes fade_in_show {
     0% {
          opacity: 0;
          transform: scale(0)
     }
     100% {
          opacity: 1;
          transform: scale(1)
     }
}
irgfx
la source
Merci pour cette astuce utile qui fonctionne parfaitement.
Sedat Kumcu
6

J'ai rencontré ce problème plusieurs fois et je suis maintenant simplement allé avec:

.block {
  opacity: 1;
  transition: opacity 250ms ease;
}

.block--invisible {
  pointer-events: none;
  opacity: 0;
}

En ajoutant la classe, block--invisiblel'ensemble des éléments ne sera pas cliquable, mais tous les éléments derrière elle le seront en raison de celui pointer-events:nonequi est pris en charge par tous les principaux navigateurs (pas d'IE <11).

DominikAngerer
la source
Pouvez-vous mettre cela en exemple, s'il vous plaît?
GarethAS
1
Cela fonctionne bien, mais il convient de noter que les événements de pointeur ne fonctionnent pas avec IE en dessous de 11
user1702965
ajout d'une note pour IE en dessous de 11
DominikAngerer
Si vous devez avoir ledit élément par-dessus tout (par exemple un menu), c'est honnêtement la façon la plus propre de le faire maintenant qu'en 2019, le support est solide pourpointer-events
Josh Davenport
5

Remplacez overflow:hiddenpar overflow:visible. Ça marche mieux. J'utilise comme ça:

#menu ul li ul {
    background-color:#fe1c1c;
    width:85px;
    height:0px;
    opacity:0;
    box-shadow:1px 3px 10px #000000;
    border-radius:3px;
    z-index:1;
    -webkit-transition:all 0.5s ease;
    -moz-transition:all 0.6s ease;
}

#menu ul li:hover ul  {
    overflow:visible;
    opacity:1;
    height:140px;
}

visiblec'est mieux car overflow:hiddenagissez exactement comme un display:none.

Jésus
la source
Celui-ci était le ticket pour moi. Merci!
Dan Loewenherz
5

JavaScript n'est pas requis, et aucune hauteur max scandaleusement énorme n'est nécessaire. Au lieu de cela, définissez votre max-heightsur vos éléments de texte et utilisez une unité relative à la police telle que remouem . De cette façon, vous pouvez définir une hauteur maximale plus grande que votre conteneur, tout en évitant un délai ou un "popping" lorsque le menu se ferme:

HTML

<nav>
  <input type="checkbox" />
  <ul>
    <li>Link 1</li>
    <li>Link 1</li>
    <li>Link 1</li>
    <li>Link 1</li>
  </ul>
</nav>

CSS

nav input + ul li { // Notice I set max-height on li, not ul
   max-height: 0;
}

nav input:checked + ul li {
   max-height: 3rem; // A little bigger to allow for text-wrapping - but not outrageous
}

Voir un exemple ici: http://codepen.io/mindfullsilence/pen/DtzjE

pleine conscience
la source
Semblable à celui-ci, vous pouvez définir la hauteur de ligne sur votre texte et le transformer à zéro. S'il n'y a que du texte à l'intérieur, cela masquera le conteneur.
vicmortelmans
Pourquoi si peu de votes? C'est une très bonne réponse et c'est peut-être celle que j'utilise.
mwilcox
@mwilcox Parce qu'il utilise une hauteur fixe, ce qui est mauvais lorsque vous travaillez avec du contenu dynamique (une hauteur estimée même). Et ce n'est utile que sur le contenu texte.
Fabian von Ellerts
5

Après que la réponse acceptée de Guillermo a été écrite, la spécification de transition CSS du 2012-04-03 a changé le comportement de la transition de visibilité et maintenant il est possible de résoudre ce problème de manière plus courte , sans utiliser de transition-delay:

.myclass > div {
                   transition:visibility 1s, opacity 1s;
                   visibility:hidden;  opacity:0
               }
.myclass:hover > div
               {   visibility:visible; opacity:1 }

Le temps d'exécution spécifié pour les deux transitions doit généralement être identique (bien qu'un temps légèrement plus long pour la visibilité ne soit pas un problème).

Pour une version en cours d'exécution, consultez mon article de blog Visibilité sur la transition CSS .

A écrit le titre de la question "Transitions sur l'écran: propriété" et en réponse aux commentaires de Rui Marques et josh à la réponse acceptée:

Cette solution fonctionne dans les cas où elle n'est pas pertinente si la propriété d'affichage ou de visibilité est utilisée (comme c'était probablement le cas dans cette question).

Il ne supprimera pas complètement l'élément comme display:none , le rendra simplement invisible, mais il restera toujours dans le flux de documents et influencera la position des éléments suivants.

Les transitions qui suppriment complètement l'élément similaire à display:nonepeuvent être effectuées en utilisant la hauteur (comme indiqué par d'autres réponses et commentaires), la hauteur max ou la marge haut / bas, mais aussi voir Comment puis-je faire la transition hauteur: 0; à hauteur: auto; en utilisant CSS? et mon article de blog Solutions de contournement pour les transitions CSS sur les propriétés d'affichage et de hauteur .

En réponse au commentaire de GeorgeMillo: Les deux propriétés et les deux transitions sont nécessaires: La propriété d'opacité est utilisée pour créer une animation de fondu d'entrée et de sortie et la propriété de visibilité pour éviter que l'élément ne réagisse toujours aux événements de la souris. Des transitions sont nécessaires sur l'opacité de l'effet visuel et sur la visibilité pour retarder le masquage jusqu'à la fin du fondu.

Helmut Emmelmann
la source
4

J'ai finalement trouvé une solution pour moi, en combinant opacityavec position absolute(pour ne pas occuper d'espace lorsqu'il est caché).

.toggle {
  opacity: 0;
  position: absolute;
  transition: opacity 0.8s;
}

.parent:hover .toggle {
  opacity: 1;
  position: static;
}
Damjan Pavlica
la source
4

Je soupçonne que n'importe qui commençant des transitions CSS découvre rapidement qu'elles ne fonctionnent pas si vous modifiez la propriété d'affichage (bloc / aucun) en même temps. Une solution de contournement qui n'a pas encore été mentionnée est que vous pouvez continuer à utiliser display:block/nonepour masquer / afficher l'élément, mais définissez son opacité sur 0 afin que même lorsqu'il l'est display:block, il soit toujours invisible.

Ensuite, pour l'ajouter en fondu, ajoutez une autre classe CSS telle que "on" qui définit l'opacité à 1 et définit la transition pour l'opacité. Comme vous l'avez peut-être imaginé, vous devrez utiliser JavaScript pour ajouter cette classe "on" à l'élément, mais au moins vous utilisez toujours CSS pour la transition réelle.

PS Si vous vous trouvez dans une situation où vous devez faire les deux display:blocket ajouter la classe "on", en même temps, différez cette dernière en utilisant setTimeout. Sinon, le navigateur ne voit que les deux choses en même temps et désactive la transition.

Larry Gerndt
la source
Excellent, merci! J'ai écrit une autre réponse avec un exemple qui fonctionne réellement display:none.
mojuba
4

C'est aussi simple que ce qui suit :)

@keyframes fadeout {
    0% { opacity: 1; height: auto; }
    90% { opacity: 0; height: auto; }
    100% { opacity: 0; height: 0;
}
animation: fadeout linear 0.5s 1 normal forwards !important;

Faites-le disparaître, puis faites-le height 0;. Assurez-vous également d'utiliser avant pour qu'il reste dans l'état final.

Veljko Simakovic
la source
Cela se réinitialiserait instantanément lors de la suppression de la classe, donc ce n'est pas une bonne idée
Sean T
2

Cette solution a une excellente compatibilité, et je ne l'ai pas encore vue:

.hidden-element {
  position: absolute;
  z-index: -1;
  pointer-events: none;
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s, opacity .5s ease-out;
}

.hidden-element.visible {
  position: static;
  z-index: auto;
  pointer-events: auto;
  visibility: visible;
  opacity: 1;
}

Explication : il utilise l' visibility: hiddenastuce (qui est compatible avec «afficher et animer» en une seule étape), mais il utilise la combinaison position: absolute; z-index: -1; pointer-events: none;pour s'assurer que le conteneur caché ne prend pas de place et ne répond pas aux interactions des utilisateurs .

Christophe Marois
la source
1
Mais le changement d' positionalambic fera trembler l'élément, non?
Arsylum
Eh bien, bien sûr: position: absolutesignifie que l'élément ne prend pas de place, comme décrit dans l'explication. Quand il passe à position: staticet apparaît, il prendra de l'espace comme un élément normal, ce qui est le point de cette question. Je vous suggère de l'essayer!
Christophe Marois
2
J'ai fait. Mais si je comprends bien, la question portait sur les transitions . Comme dans les "animations fluides".
Arsylum
2

Vous pouvez faire en sorte que cela fonctionne de la manière naturelle que vous attendiez - en utilisant l'affichage - mais vous devez limiter le navigateur pour le faire fonctionner, en utilisant Javascript ou comme d'autres ont suggéré une astuce sophistiquée avec une balise à l'intérieur d'une autre. Je ne me soucie pas de la balise interne car elle complique davantage le CSS et les dimensions, alors voici la solution Javascript:

https://jsfiddle.net/b9chris/hweyecu4/17/

Commençant par une boîte comme:

<div id="box" class="hidden">Lorem</div>

Une boîte cachée.

div.hidden {
    display: none;
}
#box {
    transition: opacity 1s;
}

Nous allons utiliser une astuce trouvée dans un Q / A connexe, en vérifiant offsetHeight pour étrangler le navigateur instantanément:

https://stackoverflow.com/a/16575811/176877

Tout d'abord, une bibliothèque formalisant l'astuce ci-dessus:

$.fn.noTrnsn = function () {
    return this.each(function (i, tag) {
        tag.style.transition = 'none';
    });
};
$.fn.resumeTrnsn = function () {
    return this.each(function (i, tag) {
        tag.offsetHeight;    
        tag.style.transition = null;
    });
};

Ensuite, nous allons l'utiliser pour révéler une boîte et l'ajouter en fondu:

$('#button').on('click', function() {
    var tag = $('#box');
    if (tag.hasClass('hidden'))
        tag.noTrnsn().removeClass('hidden')
        .css({ opacity: 0 })
        .resumeTrnsn().css({ opacity: 1 });
    else
        tag.css({ opacity: 0 });
});

Cela fait fondre la boîte dans et hors. Ainsi, .noTrnsn()se éteint transitions, puis on enlève la hiddenclasse, qui fait osciller displayde nonesa valeur par défaut, block. Nous avons ensuite défini l'opacité sur 0 pour nous préparer à un fondu. Maintenant que nous avons réglé la scène, nous réactivons les transitions, avec .resumeTrnsn(). Et enfin, lancez la transition en définissant l'opacité sur 1.

Sans la bibliothèque, le changement à afficher et le changement à l'opacité nous auraient donné des résultats indésirables. Si nous supprimions simplement les appels de bibliothèque, nous n'obtiendrions aucune transition.

Notez que ce qui précède ne redéfinit pas l'affichage à la fin de l'animation de fondu. Nous pouvons devenir plus fantaisistes cependant. Faisons-le avec un fondu qui augmente à partir de 0.

Fantaisie!

https://jsfiddle.net/b9chris/hweyecu4/22/

#box {
    transition: height 1s, opacity 1s;
}

Nous passons maintenant à la fois à la hauteur et à l'opacité. Notez que nous ne sommes pas réglage en hauteur, ce qui signifie qu'il est la valeur par défaut, auto. Conventionnellement, cela ne peut pas être effectué - le passage de l'auto à une valeur de pixel (comme 0) ne vous procurera aucune transition. Nous allons contourner cela avec la bibliothèque et une autre méthode de bibliothèque:

$.fn.wait = function (time, fn) {
    if (time)
        this.delay(time);
    if (!fn)
        return this;

    var _this = this;
    return this.queue(function (n) {
        fn.call(_this);
        n();
    });
};

Il s'agit d'une méthode pratique qui nous permet de participer à la file d'attente fx / animation existante de jQuery, sans nécessiter le cadre d'animation qui est désormais exclu dans jQuery 3.x. Je ne vais pas expliquer comment fonctionne jQuery, mais il suffit de dire, la .queue()et la .stop()plomberie que jQuery fournit de l' aide nous empêchons nos animations de marcher sur l'autre.

Animons l'effet de glissement vers le bas.

$('#button').on('click', function() {
    var tag = $('#box');
    if (tag.hasClass('hidden')) {
        // Open it
        // Measure it
        tag.stop().noTrnsn().removeClass('hidden').css({
            opacity: 0, height: 'auto'
        });
        var h = tag.height();
        tag.css({ height: 0 }).resumeTrnsn()
        // Animate it
        .css({ opacity: 1, height: h })
        .wait(1000, function() {
            tag.css({ height: 'auto' });
        });
    } else {
        // Close it
        // Measure it
        var h = tag.noTrnsn().height();
        tag.stop().css({ height: h })
        .resumeTrnsn()
        // Animate it
        .css({ opacity: 0, height: 0 })
        .wait(1000, function() {
            tag.addClass('hidden');
        });
    }
});

Ce code commence par vérifier #boxet s'il est actuellement caché, par vérifier sa classe. Mais il accomplit davantage en utilisant l' wait()appel de bibliothèque, en ajoutant la hiddenclasse à la fin de l'animation de glissement / fondu, que vous vous attendriez à trouver si elle est en fait cachée - quelque chose que l'exemple plus simple ci-dessus ne pourrait pas faire. Cela se produit également pour permettre d'afficher / masquer l'élément encore et encore, ce qui était un bogue dans l'exemple précédent, car la classe cachée n'a jamais été restaurée.

Vous pouvez également voir les changements de CSS et de classe appelés .noTrnsn()pour définir généralement le décor des animations, y compris prendre des mesures, comme mesurer la hauteur finale #boxsans le montrer à l'utilisateur, avant d'appeler .resumeTrnsn(), et l'animer à partir de cet ensemble complet étape vers ses valeurs CSS d'objectif.

Ancienne réponse

https://jsfiddle.net/b9chris/hweyecu4/1/

Vous pouvez le faire passer en un clic avec:

function toggleTransition() {
  var el = $("div.box1");

  if (el.length) {
    el[0].className = "box";
    el.stop().css({maxWidth: 10000}).animate({maxWidth: 10001}, 2000, function() {
        el[0].className = "box hidden";
    });
  } else {
    el = $("div.box");
    el[0].className = "box";
    el.stop().css({maxWidth: 10001}).animate({maxWidth: 10000}, 50, function() {
        el[0].className = "box box1";
    });
  }

  return el;
}

someTag.click(toggleTransition);

Le CSS est ce que vous devinez:

.hidden {
    display: none;
}
.box {
    width: 100px;
    height: 100px;
    background-color: blue;
    color: yellow;
    font-size: 18px;
    left: 20px;
    top: 20px;
    position: absolute;
    -webkit-transform-origin: 0 50%;
    transform-origin: 0 50%;
    -webkit-transform: scale(.2);
    transform: scale(.2);
    -webkit-transition: transform 2s;
    transition: transform 2s;
}
.box1{
    -webkit-transform: scale(1);
    transform: scale(1);
}

La clé réduit la propriété d'affichage. En supprimant la classe cachée, puis en attendant 50 ms, puis en démarrant la transition via la classe ajoutée, nous la faisons apparaître puis nous nous développons comme nous le voulions, au lieu de simplement la faire apparaître sur l'écran sans aucune animation. La même chose se produit dans l'autre sens, sauf que nous attendons que l'animation soit terminée avant d'appliquer caché.

Remarque: j'abuse .animate(maxWidth)ici pour éviter les setTimeoutconditions de course. setTimeoutest rapide pour introduire des bogues cachés lorsque vous ou quelqu'un d'autre récupérez du code sans le savoir. .animate()peut facilement être tué avec .stop(). Je l'utilise simplement pour mettre un retard de 50 ms ou 2000 ms sur la file d'attente fx standard où il est facile de trouver / résoudre par d'autres codeurs en s'appuyant sur cela.

Chris Moschini
la source
1

J'ai eu un problème similaire auquel je n'ai pas trouvé de réponse. Plus tard, quelques recherches sur Google m'ont conduit ici. Considérant que je n'ai pas trouvé la réponse simple que j'espérais, je suis tombé sur une solution à la fois élégante et efficace.

Il s'avère que la visibilitypropriété CSS a une valeur collapsequi est généralement utilisée pour les éléments de table. Cependant, s'il est utilisé sur d'autres éléments, il les rend effectivement masqués , à peu près comme display: hiddenmais avec la possibilité supplémentaire que l'élément ne prenne pas de place et vous pouvez toujours animer l'élément en question.

Voici un exemple simple de cela en action.

function toggleVisibility() {
  let exampleElement = document.querySelector('span');
  if (exampleElement.classList.contains('visible')) {
    return;
  }
  exampleElement.innerHTML = 'I will not take up space!';
  exampleElement.classList.toggle('hidden');
  exampleElement.classList.toggle('visible');
  setTimeout(() => {
    exampleElement.classList.toggle('visible');
    exampleElement.classList.toggle('hidden');
  }, 3000);
}
#main {
  display: flex;
  flex-direction: column;
  width: 300px;
  text-align: center;
}

.hidden {
  visibility: collapse;
  opacity: 0;
  transition: visibility 2s, opacity 2s linear;
}

.visible {
  visibility: visible;
  opacity: 1;
  transition: visibility 0.5s, opacity 0.5s linear;
}
<div id="main">
  <button onclick="toggleVisibility()">Click Me!</button>
  <span class="hidden"></span>
  <span>I will get pushed back up...</span>
</div>

Deadmano
la source
1

La solution universelle la plus simple au problème est: n'hésitez pas à spécifier display:nonedans votre CSS, mais vous devrez le changer en block(ou quoi que ce soit d'autre) en utilisant JavaScript, puis vous devrez également ajouter une classe à votre élément en question qui en fait fait la transition avec setTimeout () . C'est tout.

C'est à dire:

<style>
    #el {
        display: none;
        opacity: 0;
    }
    #el.auto-fade-in {
        opacity: 1;
        transition: all 1s ease-out; /* Future, future, please come sooner! */
        -webkit-transition: all 1s ease-out;
        -moz-transition: all 1s ease-out;
        -o-transition: all 1s ease-out;
    }
</style>

<div id=el>Well, well, well</div>

<script>
    var el = document.getElementById('el');
    el.style.display = 'block';
    setTimeout(function () { el.className = 'auto-fade-in' }, 0);
</script>

Cela a été testé dans les derniers navigateurs sains. Évidemment, cela ne devrait pas fonctionner dans Internet Explorer 9 ou une version antérieure.

mojuba
la source
1

Je pense que SalmanPK a la réponse la plus proche. Il fait fondre un élément vers l'intérieur ou l'extérieur, avec les animations CSS suivantes. Cependant, la propriété d'affichage ne s'anime pas en douceur, seulement l'opacité.

@-webkit-keyframes fadeIn {
    from { opacity: 0; }
      to { opacity: 1; }
}

@-webkit-keyframes fadeOut {
    from { opacity: 1; }
      to { opacity: 0; }
}

Si vous souhaitez animer l'élément en passant d'un bloc d'affichage à aucun affichage, je ne vois pas que c'est actuellement possible uniquement avec CSS. Vous devez obtenir la hauteur et utiliser une animation CSS pour diminuer la hauteur. Cela est possible avec CSS comme indiqué dans l'exemple ci-dessous, mais il serait difficile de connaître les valeurs de hauteur exactes dont vous avez besoin pour animer un élément.

Exemple jsFiddle

CSS

@-webkit-keyframes pushDown {
  0% {
    height: 10em;
  }
  25% {
    height: 7.5em;
  }
  50% {
    height: 5em;
  }
  75% {
    height: 2.5em;
  }
  100% {
    height: 0em;
  }
}

.push-down {
    -webkit-animation: pushDown 2s forwards linear;
}

Javascript

var element = document.getElementById("element");

// Push item down
element.className = element.className + " push-down";
svnm
la source
1

Vous pouvez le faire avec des événements de transition, vous créez donc deux classes CSS pour la transition, l'une contenant l'animation, l'autre affichant l'état aucun. Et vous les changez une fois l'animation terminée? Dans mon cas, je peux afficher à nouveau les divs si j'appuie sur un bouton et supprimer les deux classes.

Essayez l'extrait ci-dessous ...

$(document).ready(function() {
  // Assign transition event
  $("table").on("animationend webkitAnimationEnd", ".visibility_switch_off", function(event) {
    // We check if this is the same animation we want
    if (event.originalEvent.animationName == "col_hide_anim") {
      // After the animation we assign this new class that basically hides the elements.
      $(this).addClass("animation-helper-display-none");
    }

  });

  $("button").click(function(event) {

    $("table tr .hide-col").toggleClass(function() {
      // We switch the animation class in a toggle fashion...
      // and we know in that after the animation end, there
      // is will the animation-helper-display-none extra
      // class, that we nee to remove, when we want to
      // show the elements again, depending on the toggle
      // state, so we create a relation between them.
      if ($(this).is(".animation-helper-display-none")) {
        // I'm toggling and there is already the above class, then
        // what we want it to show the elements , so we remove
        // both classes...
        return "visibility_switch_off animation-helper-display-none";
      }
      else {
        // Here we just want to hide the elements, so we just
        // add the animation class, the other will be added
        // later be the animationend event...
        return "visibility_switch_off";
      }
    });
  });
});
table th {
  background-color: grey;
}

table td {
  background-color: white;
  padding: 5px;
}

.animation-helper-display-none {
  display: none;
}

table tr .visibility_switch_off {
  animation-fill-mode: forwards;
  animation-name: col_hide_anim;
  animation-duration: 1s;
}

@-webkit-keyframes col_hide_anim {
  0% {opacity: 1;}
  100% {opacity: 0;}
}

@-moz-keyframes col_hide_anim {
  0% {opacity: 1;}
  100% {opacity: 0;}
}

@-o-keyframes col_hide_anim {
  0% {opacity: 1;}
  100% {opacity: 0;}
}

@keyframes col_hide_anim {
  0%   {opacity: 1;}
  100% {opacity: 0;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <theader>
    <tr>
      <th>Name</th>
      <th class='hide-col'>Age</th>
      <th>Country</th>
    </tr>
  </theader>
  <tbody>
    <tr>
      <td>Name</td>
      <td class='hide-col'>Age</td>
      <td>Country</td>
    </tr>
  </tbody>
</table>

<button>Switch - Hide Age column with fadeout animation and display none after</button>

Miguel
la source
0

Si vous utilisez jQuery pour définir vos classes, cela fonctionnera à 100%:

$(document).ready(function() {
  $('button').click(function() {
    var container = $('.container');
    
    if (!container.hasClass('active')) {
      container.addClass('show').outerWidth();
      container.addClass('active');
    }
    else {
      container.removeClass('active').one('transitionend', function() {
        container.removeClass('show');
      });
    }
  });
});
.container {
  display: none;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.container.show {
  display: flex;
}
 
.container.active {
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button">Toggle</button>

<div class="container">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>

Bien sûr, vous pouvez simplement utiliser jQuery .fadeIn()et les .fadeOut()fonctions, mais l'avantage de définir des classes à la place est au cas où vous voudriez passer à une valeur d'affichage autre que block(comme c'est le cas par défaut avec .fadeIn()et .fadeOut()).

Ici, je passe à l'affichage flexavec un bel effet de fondu.

GSTAR
la source
0

Au lieu de l'utiliser, displayvous pouvez stocker l'élément «hors écran» jusqu'à ce que vous en ayez besoin, puis définir sa position à l'endroit où vous le souhaitez et le transformer en même temps. Cela soulève cependant une foule d'autres problèmes de conception, de sorte que votre kilométrage peut varier.

Vous ne voudriez probablement pas utiliser de displaytoute façon, car vous voudriez que le contenu soit accessible aux lecteurs d'écran, qui essaient pour la plupart de respecter les règles de visibilité - c'est-à-dire, s'il ne devrait pas être visible à l'œil, il n'apparaîtra pas comme contenu à l'agent.

Peter Mortensen
la source
0

Vous pouvez simplement utiliser la visibilité CSS : caché / visible au lieu de l' affichage : aucun / bloc

div {
    visibility:hidden;
    -webkit-transition: opacity 1s ease-out;
    -moz-transition: opacity 1s ease-out;
    -o-transition: opacity 1s ease-out;
    transition: opacity 1s ease-out;
    opacity: 0;
}

parent:hover > div {
    opacity: 1;
    visibility: visible;
}
foxdanni
la source
5
Cela réserve cependant de l'espace, laissant un trou vide. Si vous souhaitez réduire un espace, vous devez animer la hauteur ou une autre propriété.
Marcy Sutton
0

J'ai commencé un projet squelette open source appelé Toggle Display Animate .

Cet assistant squelette vous permettra d'imiter facilement jQuery show / hide, mais avec des animations de transition CSS 3 in / out.

Il utilise des bascules de classe afin que vous puissiez utiliser toutes les méthodes CSS que vous souhaitez sur les éléments en plus de l'affichage: aucun | bloc | table | en ligne, etc. ainsi que d'autres utilisations alternatives qui peuvent être envisagées.

Son objectif principal de conception est de basculer les états des éléments, et il prend en charge un état de retour où le masquage de l'objet vous permet d'exécuter votre image clé en sens inverse ou de jouer une animation alternative pour masquer l'élément.

La plupart du balisage pour le concept sur lequel je travaille est CSS, et il y a très peu de JavaScript réellement utilisé.

Il y a une démo ici: http://marcnewton.co.uk/projects/toggle-display-animate/

Marc
la source