web-dev-qa-db-fra.com

Transitions sur l'affichage: propriété

Je conçois actuellement un menu "méga-liste déroulante" CSS, essentiellement un menu déroulant standard, mais qui contient différents types de contenu.

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

À partir de l'exemple ci-dessus, peut-on imaginer un moyen de fondre le menu de deuxième niveau lorsque quelqu'un survole l'un des éléments de menu de niveau supérieur?

Je suis conscient que vous pouvez utiliser des transitions sur la propriété visibility:, mais je ne trouve pas de moyen de l'utiliser efficacement.

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

Je sais aussi qu'il est trivial de réaliser cela en JavaScript, mais je voulais me lancer un défi d'utiliser uniquement du CSS et je pense que je vais être un peu court.

Toutes les suggestions sont les bienvenues.

1279
RichardTape

Vous pouvez concaténer deux transitions ou plus, et visibility est ce qui vous convient le mieux cette fois-ci.

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 de fournisseur associés à la propriété transition.)

Plus de détails sont dans cet article

1219
Guillermo

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

J'ai réalisé l'effet en plaçant les deux <div>s de manière absolue et en définissant celui qui est caché sur opacity: 0.

Si vous basculez même la propriété display de none à block, 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 des moyens suivants:

  1. Réglez le height sur 0.
  2. Réglez le opacity sur 0.
  3. Positionnez l'élément en dehors du cadre d'un autre élément contenant overflow: hidden.

Il existe probablement d'autres solutions, mais vous ne pouvez pas effectuer de transition si vous basculez l'élément sur 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 va pas fonctionner. D'après mon expérience, j'ai constaté que cela ne faisait rien.

Pour cette raison, vous aurez toujours besoin de conserver l'élément display: block - mais vous pouvez le contourner en procédant de la manière suivante:

div {
    transition: opacity 1s ease-out;
    opacity: 0; 
    height: 0;
    overflow: hidden;
}
div.active {
    opacity: 1;
    height: auto;
}
741
Jim Jeffers

Au moment de la publication de ce message, tous les principaux navigateurs désactivent les transitions CSS si vous essayez de modifier la propriété display, mais les animations CSS fonctionnent toujours correctement et nous pouvons donc 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; }
}

Appliquez ensuite l’animation fadeIn à l’enfant sur le survol parent: - (et bien sûr définissez display: block)

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

Mise à jour 2019 - Méthode prenant également en charge le fondu en fondu:

(Certains JS 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>
251
Salman for Hire

Je soupçonne que le raison que les transitions sont désactivées si "affichage" est modifié, cela est dû à ce que l'affichage fait réellement. Cela pas change tout ce qui pourrait éventuellement être animé en douceur.

"Display: none" et "visibilité: hidden" sont deux entièrement choses différentes. Les deux ont pour effet de rendre l'élément invisible, mais avec "visibilité: masqué"; il est toujours restitué dans la présentation, mais pas visiblement oui. L'élément masqué occupe toujours de la place et est toujours restitué en ligne ou sous forme de bloc ou de bloc en ligne ou sous forme de tableau, ou quoi que l'élément "display" lui indique de rendre en tant que, et occupe de l'espace en conséquence. Les autres éléments not se déplacent automatiquement pour occuper cet espace. L’élément masqué ne rend pas ses pixels réels à la sortie.

“Display: none” en revanche empêche l'élément de rendre entièrement. Il ne prend pas aucun espace de mise en page. D’autres éléments qui auraient occupé tout ou partie de l’espace occupé par cet élément s’ajustent maintenant pour occuper cet espace, comme si l’élément était simplement n’existait pas du tout.

"Display" n'est pas simplement un autre attribut visuel. Il établit l’ensemble du mode de rendu de l’élément, qu’il s’agisse d’un bloc, d’un inline, d’un inline-block, d’un tableau, d’une rangée de tableau, d’une cellule de tableau, d’un élément de liste ou autre! Chacune de celles-ci a des ramifications de mise en page très différentes, et il n'y aurait pas de moyen raisonnable de les animer ou de les faire passer en douceur (essayez d'imaginer une transition en douceur de "bloc" à "en ligne" ou vice-versa, par exemple!).

C’est la raison pour laquelle les transitions sont désactivées si l’affichage change (même s’il s’agit de “none” - “none” n’est pas simplement invisible, c’est son propre mode de rendu d’éléments qui signifie aucun rendu du tout!),

64
Joel_MMCC

display n'est pas l'une des propriétés sur lesquelles la transition fonctionne.

Voir https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties pour obtenir la liste des propriétés CSS auxquelles des transitions peuvent être appliquées. Voir https://drafts.csswg.org/css-values-4/#combining-values pour savoir comment elles sont interpolées.

Jusqu'à CSS3 a été répertorié dans https://www.w3.org/TR/2017/WD-css-transitions-1-20171130/#animatable-css (il suffit de fermer la fenêtre d'avertissement)

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

La dernière fois que j'ai eu à faire cela, j'ai utilisé max-height à la place, qui est une propriété pouvant être animée (bien que ce fût un peu un bidouillage, cela a fonctionné), mais méfiez-vous, cela peut être très plaisant pour des pages complexes fin des appareils mobiles.

49
robocat

Je sais que la question est très ancienne, mais pour les personnes qui consultent ce fil de discussion, vous pouvez maintenant ajouter une animation personnalisée à la propriété block.

@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émonstration, le sous-menu change de display:none à display:block et parvient toujours à s’affaiblir.

35
Manish Pradhan

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

#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, qu'est-ce qui se passe ici?

  1. Lorsque la classe visible est ajoutée, height et opacity démarrent l'animation sans délai (0 ms), bien que height prenne 0 ms pour terminer l'animation (équivalent de display: block). et opacity prend 600 ms.

  2. Lorsque la classe visible est supprimée, opacity dé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 (équivalent de display: none dans l'animation rappeler).

Notez que cette approche est meilleure que celles utilisant visibility. Dans ce cas, l’élément occupe toujours l’espace de la page et il ne convient pas toujours.

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

34
Webars

Selon Projet de travail du W3C du 19 novembre 201display n'est pas une propriété animable . Heureusement, visibility est animable. Vous pouvez chaî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 faites simplement que le lien soit transparent, sans définir visibility: hidden, il restera alors cliquable.

20
feklee

Mon astuce JavaScript soignée est pour séparer tout le scénario 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!

13
Sasa Milenkovic

Éditer: 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 configuré pour bloquer tandis que l'opacité s'estompe. Au dernier moment, la propriété d'affichage est définie sur none.

Et le plus important est de conserver la dernière image à la fin de l’animation en utilisant animation-fill-mode:

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

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

12
Pawel

Je me suis heurté à cela aujourd'hui, avec un modal _position: fixed_ que je réutilisais. Je ne pouvais pas le garder _display: none_ puis l'animer, car il apparaissait de nouveau dans l'apparence et _z-index_ (valeurs négatives, etc.) faisait également des choses étranges.

J'utilisais également un _height: 0_ à _height: 100%_, mais cela ne fonctionnait que lorsque le modal est apparu. C'est la même chose que si vous utilisiez _left: -100%_ ou quelque chose comme ça.

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

D'abord votre modal caché. Notez que la height est _0_ et consultez la déclaration height dans les transitions ... elle a un _500ms_, qui est plus long que ma transition opacity. Rappelez-vous que ceci affecte la transition de fondu sortant: ramener le 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éfinissiez un _.modal-active_ à la body. Maintenant, la height est _100%_ et ma transition a également changé. Je souhaite que la height soit instantanément modifiée et que opacity prenne _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 à merveille.

10
hotmeteor

En prenant quelques-unes de ces réponses et quelques suggestions ailleurs, les éléments suivants sont parfaits pour les menus survolés (je l’utilise 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-height si vous spécifiez les deux valeurs, car height:auto n'est pas autorisé avec transitions. La valeur de survol de max-height doit être supérieure à la valeur possible de height du menu.

8
Edyn

Remplacez overflow:hidden par 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;
}

visible est préférable car overflow:hidden se comporte exactement comme un display:none.

6
jesus

Après la réponse acceptée de Guillermo, la spécification de transition CSS du 3 avril 2012 a modifié le comportement de la transition de visibilité et permet désormais de résoudre ce problème plus rapidement , sans utilisation 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 pose pas de problème). Pour une version en cours d'exécution, voir mon blog http://www.taccgl.org/blog/css-transition-visibility.html#visibility-opacity .

W.r.t. le titre de la question "Transitions à 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ù il est indifférent que la propriété d'affichage ou de visibilité soit utilisée (comme c'était probablement le cas dans cette question). L'élément affiché ne sera pas complètement supprimé: aucun, mais restez invisible mais reste dans le flux de documents et influence la position des éléments suivants. Les transitions qui suppriment complètement l'élément ressemblent à l'affichage: aucune ne peut être effectuée en utilisant la hauteur (comme indiqué par d'autres réponses et commentaires), la hauteur maximale ou la marge haut/bas, mais aussi la section Comment puis-je changer la hauteur: 0; to height: auto; using CSS? et mon blog http://www.taccgl.org/blog/css_transition_display.html .

En réponse au commentaire de GeorgeMillo: Les propriétés et les deux transitions sont nécessaires: La propriété opacity est utilisée pour créer une animation en fondu en entrée et en sortie, ainsi que la propriété de visibilité pour éviter que l'élément ne réagisse encore lors d'événements de 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.

5
Helmut Emmelmann

Pas de javascript requis, ni de max-height excessivement énorme. Au lieu de cela, définissez votre hauteur maximale sur vos éléments de texte et utilisez une unité de police relative telle que rem ou em. De cette façon, vous pouvez définir une hauteur maximale supérieure à celle de votre conteneur, tout en évitant un délai ou un "popping" à la fermeture du menu:

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

5
mindfullsilence

Je suis tombé sur ce problème à plusieurs reprises et je me suis contenté de:

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

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

En ajoutant la classe block--invisible l'ensemble des éléments ne sera pas cliquable, mais tous les éléments cachés derrière le seront en raison du pointer-events:none pris en charge par tous les principaux navigateurs (pas de IE <11). .

4
DominikAngerer

Je soupçonne que quelqu'un qui commence à peine des transitions CSS découvre rapidement qu'elles ne fonctionnent pas si vous modifiez la propriété d'affichage (block/none) en même temps. Une solution qui n’a pas encore été mentionnée est que vous pouvez continuer à utiliser display: block/none pour masquer/afficher l’élément, mais définissez son opacité sur 0 afin que, même si display: block, il soit toujours invisible. Ajoutez ensuite une autre classe CSS, telle que "on", qui définit l'opacité sur 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.

P.S. Si vous vous trouvez dans une situation où vous devez faire les deux, afficher: bloquer et ajouter la classe "on", en même temps, différer cette dernière à l'aide de setTimeout. Sinon, le navigateur considère que les deux événements se produisent simultanément et désactive la transition.

4
Larry Gerndt

J'ai finalement trouvé une solution pour moi, en combinant opacity avec position absolute (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;
}
3
Damjan Pavlica

Je pense que SalmanPK a la réponse la plus proche, il fade un élément en entrée ou en sortie, avec les animations CSS suivantes. Cependant, la propriété display n'anime pas correctement, seule 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 déplacé du bloc d'affichage pour qu'il n'en affiche aucun, je ne vois pas que c'est actuellement possible uniquement avec CSS, vous devez obtenir la hauteur et utiliser une animation CSS pour la diminuer. Cela est possible avec CSS, comme illustré dans l'exemple ci-dessous, mais il serait difficile de connaître les valeurs de hauteur exactes que vous devez animer pour un élément.

jsFiddle exemple

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";
2
svnm

Je me sens presque mal de répondre à une question avec autant de réponses, mais cette solution offre 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'astuce visibility: hidden (compatible avec "afficher et animer" en une étape) mais utilise la combinaison position: absolute; z-index: -1; pointer-events: none; pour s'assurer que le conteneur caché ne prend pas d'espace et ne répond pas aux interactions de l'utilisateur.

2

Aussi simple que :)

@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 et que sa hauteur soit de 0; Veillez également à utiliser les avants pour qu'il reste dans l'état final.

2
Veljko Simakovic

Au lieu d'utiliser l'affichage, vous pouvez stocker l'élément "hors écran" jusqu'à ce que vous en ayez besoin, puis définir sa position à l'endroit souhaité et le transformer en même temps. Cela soulève cependant une foule d'autres problèmes de conception, donc ymmv. Vous ne voudriez probablement pas utiliser l’affichage de toute façon, car vous voudriez que le contenu soit accessible aux lecteurs d’écran, qui essaient pour la plupart d’obéir aux règles de visibilité - c’est-à-dire s’il ne devrait pas être visible à l’œil, cela n'apparaîtra pas comme contenu pour l'agent.

1
user164226

Vous pouvez le faire avec des événements de transition. Ainsi, vous créez ainsi deux classes CSS pour la transition, l'une tenant l'animation d'autre, tenant l'état d'affichage aucun. et vous les permutez une fois l'animation terminée? Dans mon cas, je peux afficher à nouveau les divs si j'appuie sur un BTN et supprimer les deux classes.

Essayez le coupé 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")) {
        //im toggleing and there is already the above classe, 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>
1
Miguel

J'ai eu un problème similaire auquel je n'ai pas trouvé de réponse. Quelques recherches sur Google m'ont conduit plus tard ici. Considérant que je ne trouvais pas 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 propriété visibility CSS a la valeur collapse qui 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 comme caché, à peu près la même chose que display: hidden mais avec la possibilité supplémentaire que l'élément n'occupe aucun espace et vous pouvez continue d’animer l’élément en question.

Vous trouverez ci-dessous un exemple simple de cette 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>
1
Deadmano

La solution universelle la plus simple au problème est la suivante: n'hésitez pas à spécifier display:none dans votre CSS, mais vous devrez le modifier en block (ou autre) à l'aide de JavaScript, puis vous devrez également ajoutez à votre élément en question une classe qui effectue effectivement 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>

Testé dans les derniers navigateurs sains. Évidemment, ne devrait pas fonctionner dans IE9 ou plus tôt.

1
mojuba

vous pouvez aussi utiliser ceci:

.dropdown {
height: 0px;
width: 0px;
opacity: .0;
color: white;
}
.dropdown:hover {
height: 20px;
width: 50px;
opacity: 1;
transition: opacity 200ms;
/* Safari */
-webkit-transition: opacity 200ms;
}
0
user2615031

Vous pouvez obtenir que cela fonctionne de la manière naturelle que vous espériez - en utilisant l'affichage - mais vous devez étrangler le navigateur pour que cela fonctionne, en utilisant soit JS, soit comme d'autres suggèrent un tour de fantaisie avec une étiquette dans une autre. Je me moque de la balise interne car elle complique davantage les CSS et les dimensions. Voici donc la solution JS:

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

Commençant par une boîte comme:

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

Une boîte cachée Vous pouvez avoir la transition sur 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 devineriez:

.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é limite la propriété display. En supprimant la classe cachée puis en attendant 50ms, puis en démarrant la transition via la classe ajoutée, nous la faisons apparaître et ensuite nous développons comme nous le souhaitions, au lieu de il suffit de passer sur l'écran sans aucune animation. Des événements similaires se produisent dans l'autre sens, sauf que nous attendons la fin de l'animation avant d'appliquer caché.

Remarque: j'abuse de .animate(maxWidth) ici pour éviter setTimeout des conditions de concurrence. setTimeout introduit rapidement des bogues cachés lorsque vous ou une autre personne récupérez du code sans le savoir. .animate() peut facilement être tué avec .stop(). Je l'utilise simplement pour mettre un délai de 50 ms ou 2 000 ms sur la file d'attente fx standard où il est facile de trouver/résoudre par d'autres codeurs s'appuyant sur cela.

0
Chris Moschini

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

https://marcnewton.github.io/Toggle-Display-Animate/

Cet assistant squelette vous permettra d’imiter facilement l’affichage/masquage de jQuery mais avec des animations de transition CSS3 in/out.

Il utilise des bascules de classe pour que vous puissiez utiliser toutes les méthodes CSS que vous voulez sur des éléments en plus de display: none: block | table | inline, etc., ainsi que d'autres utilisations pouvant être imaginées.

Son objectif principal est de permettre aux états de basculer les éléments. Il prend en charge un état de restauration dans lequel masquer l'objet vous permet d'exécuter votre image clé à l'envers ou de lire une autre animation pour masquer l'élément.

La majeure partie du balisage du concept sur lequel je travaille est CSS, très peu de javascript est réellement utilisé.

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

0
Marc Newton

Vous pouvez simplement utiliser css visibilité: caché/visible au lieu de affichage: aucun/bloquer

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

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 les fonctions jQuery .fadeIn() et .fadeOut(), mais l'avantage de la définition de classes réside dans le fait que vous souhaitez passer à une valeur d'affichage autre que block (comme par défaut). avec .fadeIn() et .fadeOut()).

Ici, je suis en train de passer à l'affichage flex avec un effet de fondu agréable.

0
GSTAR