Übergänge in der CSS-Anzeigeeigenschaft

1447

Ich entwerfe derzeit ein CSS-Mega-Dropdown-Menü - im Grunde ein reguläres Nur-CSS-Dropdown-Menü, das jedoch verschiedene Arten von Inhalten enthält.

Im Moment scheinen CSS 3-Übergänge nicht für die Eigenschaft 'display' zu gelten , dh Sie können keinen Übergang von display: nonezu display: block(oder eine beliebige Kombination) durchführen.

Gibt es eine Möglichkeit für das Menü der zweiten Ebene aus dem obigen Beispiel, "einzublenden", wenn jemand über einem der Menüelemente der obersten Ebene schwebt?

Ich bin mir bewusst, dass Sie Übergänge auf dem visibility:Grundstück verwenden können, aber ich kann mir keine Möglichkeit vorstellen, dies effektiv zu nutzen.

Ich habe auch versucht, Höhe zu verwenden, aber das ist kläglich gescheitert.

Ich bin mir auch bewusst, dass es trivial ist, dies mit JavaScript zu erreichen, aber ich wollte mich herausfordern, nur CSS zu verwenden, und ich denke, ich komme ein wenig zu kurz.

RichardTape
quelle
Funktioniert der CSS-Übergang, wenn Sie ihn auf die Opazitätseigenschaft anwenden und nicht anzeigen?
Paul D. Waite
13
Position: absolut; Sichtbarkeit: versteckt; ist dasselbe wie Anzeige: keine;
Jawad
8
@Jawad: Nur wenn du auch so etwas hinzufügst z-index:0.
DanMan
7
@Jawad: Es wird empfohlen, es niemals zu verwenden, es visibility: hiddensei denn, Sie möchten, dass Bildschirmleser es lesen (während typische Browser dies nicht tun ). Es definiert nur die Sichtbarkeit des Elements (wie gesagt opacity: 0), und es ist immer noch auswählbar, anklickbar und was auch immer es war; es ist einfach nicht sichtbar.
Forest Katsch
1
Keine Unterstützung für pointer-eventsin IE 8,9,10, daher ist es nicht immer in Ordnung
Steven Pribilinskiy

Antworten:

1351

Sie können zwei oder mehr Übergänge verketten visibility. Diesmal ist dies praktisch.

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>

(Vergessen Sie nicht die Herstellerpräfixe der transitionEigenschaft.)

Weitere Details finden Sie in diesem Artikel .

Guillermo
quelle
10
Diese Antwort scheint weniger Arbeit zu sein als die anderen und erreicht das, was wir von der Anzeige erwarten würden: keine / Block; Vielen Dank. Hat mir eine Menge Zeit gespart.
Brendan
21
Ja, das Problem dabei ist, dass sich alles dahinter überlappt, auch wenn es nicht sichtbar ist. Ich fand mit height: 0 eine viel bessere Lösung
Josh Bedo
740
Das ist schön, aber das Problem ist, dass "Sichtbarkeit verborgen" -Elemente immer noch Platz einnehmen, während "Keine anzeigen" dies nicht tut.
Rui Marques
41
Mir fehlt wahrscheinlich etwas, aber warum ändern Sie sowohl die Sichtbarkeit als auch die Deckkraft? Wenn Sie die Deckkraft nicht auf 0 setzen, wird das Element ausgeblendet. Warum müssen Sie die Sichtbarkeit auch auf "Ausblenden" setzen?
GMA
21
@GeorgeMillo Wenn Sie nur die Deckkraft festlegen, befindet sich das Element tatsächlich noch in der Seitenwiedergabe (Sie können beispielsweise nicht auf Gedanken klicken).
Adriendenat
800

Sie müssen das Element auf andere Weise ausblenden, damit dies funktioniert.

Ich habe den Effekt erreicht, indem ich beide <div>s absolut positioniert und das versteckte auf gesetzt habe opacity: 0.

Wenn Sie sogar Toggle die displayEigenschaft aus , noneum blockIhren Übergang auf andere Elemente werden nicht auftreten.

Um dies zu umgehen, lassen Sie das Element immer zu display: block, verbergen Sie es jedoch, indem Sie eine der folgenden Methoden anpassen:

  1. Stellen Sie das heightauf 0.
  2. Stellen Sie das opacityauf 0.
  3. Positionieren Sie das Element außerhalb des Rahmens eines anderen Elements mit overflow: hidden.

Es gibt wahrscheinlich mehr Lösungen, aber Sie können keinen Übergang ausführen, wenn Sie das Element auf umschalten display: none. Sie können beispielsweise versuchen, Folgendes zu versuchen:

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

Das wird aber nicht funktionieren. Aus meiner Erfahrung habe ich festgestellt, dass dies nichts tut.

Aus diesem Grund müssen Sie das Element immer behalten display: block- aber Sie können es umgehen, indem Sie Folgendes tun:

div {
    transition: opacity 1s ease-out;
    opacity: 0;
    height: 0;
    overflow: hidden;
}
div.active {
    opacity: 1;
    height: auto;
}
Jim Jeffers
quelle
29
Danke Jim für eine gründliche Antwort. Sie haben absolut Recht damit, dass ALLE Ihre Übergänge nicht funktionieren, wenn sich die Eigenschaft display: überhaupt ändert. Was schade ist - ich frage mich, was die Gründe dafür sind. Nebenbei bemerkt, auf demselben Link, den ich in der ursprünglichen Frage gepostet habe, können Sie sehen, wo ich mich damit befinde. Das einzige (kleine) Problem, das ich habe, ist in Chrome [5.0.375.125], wenn die Seite geladen wird. Sie können sehen, dass das Menü schnell ausgeblendet wird, wenn die Elemente auf die Seite geladen werden. Firefox 4.0b2 und Safari 5.0 sind absolut in Ordnung ... Fehler oder etwas, das ich verpasst habe?
RichardTape
7
Ich bin damit einverstanden, dass dies richtig ist und dies beitragen wird; ein Heads-up für zukünftige Reisende. Ich habe eine funktionierende Lösung in Chrome gefunden, aber ich habe festgestellt, dass sie auf dem iPhone 4 fehlschlägt: visibility:hidden; opacity:0; -webkit-transition: all .2s ease-in-out;Dies geht nicht nur nicht richtig über, sondern das Zielelement wird niemals angezeigt. Die Qualitätssicherung wird Sie, mich und Ihre Mutter im Stich lassen.
SimplGy
1
Sie können die Sichtbarkeitseigenschaft auch tatsächlich
ändern
2
Wenn Sie Ihren verborgenen Status auf setzen height: 0;und ihn nicht ändern, funktioniert der Übergang nicht. Ich habe dies versucht, nur um die Deckkraft zu ändern. Ich musste denheight: 0;
chovy
10
Sie haben gerade eine Abstimmung gewonnen, weil overflow: hiddenSie sich vielmals bedankt haben!
Thiagoh
279

Zum Zeitpunkt dieses Beitrags deaktivieren alle gängigen Browser CSS-Übergänge, wenn Sie versuchen, die displayEigenschaft zu ändern. CSS-Animationen funktionieren jedoch weiterhin einwandfrei, sodass wir sie als Problemumgehung verwenden können.

Beispielcode (Sie können ihn entsprechend auf Ihr Menü anwenden) Demo :

Fügen Sie Ihrem Stylesheet das folgende CSS hinzu:

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

Wenden Sie dann die fadeInAnimation auf das Kind an, wenn Sie den Mauszeiger bewegen (und natürlich festlegen display: block):

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

Update 2019 - Methode, die auch das Ausblenden unterstützt:

(Etwas JavaScript-Code ist erforderlich)

// 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
quelle
3
Danke dafür. Der height: 0oben erwähnte Trick (für Übergänge) scheint nicht zu funktionieren, da die Höhe beim Ausblenden des Übergangs auf 0 gesetzt wird, aber dieser Trick scheint gut zu funktionieren.
Elliot Winkler
41
Danke, sehr nützlich. Aber wie kann man es ausblenden?
Illiou
1
Der erste Absatz dieser Antwort macht keinen Sinn. Browser deaktivieren nicht einfach alle Übergänge sofort, sobald Sie die displayEigenschaft nutzen - es gibt wirklich keinen Grund dafür. Und selbst wenn sie taten , warum sollte Animationen arbeiten dann? Sie können die displayEigenschaft auch nicht in CSS-Animationen verwenden.
BoltClock
7
Beste Antwort, nicht möglich mit Übergängen, aber ja mit Animationen.
Mikel
6
Wie wäre es mit umgekehrter Animation, wenn das Element dann langsam verschwinden sollte?
Grün
77

Ich vermute, dass der Grund dafür, dass Übergänge deaktiviert werden, wenn sie displaygeändert werden, darin liegt, was die Anzeige tatsächlich tut. Es ist nicht alles ändern , die möglicherweise reibungslos animiert werden könnten.

display: none;und visibility: hidden;sind zwei völlig verschiedene Dinge.
Beide haben den Effekt, dass das Element unsichtbar gemacht wird, aber visibility: hidden;es wird immer noch im Layout gerendert, aber nur nicht sichtbar .
Das versteckte Element nimmt immer noch Platz ein und wird immer noch inline oder als Block oder Block-Inline oder Tabelle oder was auch immer das displayElement zum Rendern vorschreibt, und nimmt entsprechend Platz ein.
Andere Elemente bewegen sich nicht automatisch, um diesen Raum einzunehmen. Das versteckte Element rendert einfach nicht seine tatsächlichen Pixel für die Ausgabe.

display: noneAuf der anderen Seite wird tatsächlich verhindert, dass das Element vollständig gerendert wird .
Es nimmt keinen Layoutplatz ein.
Andere Elemente, die einen Teil oder den gesamten von diesem Element eingenommenen Raum belegt hätten, passen sich jetzt an, um diesen Raum zu belegen, als ob das Element einfach überhaupt nicht existiert hätte .

displayist nicht nur ein weiteres visuelles Attribut.
Er stellt den gesamten Rendering - Modus des Elements, wie etwa , ob es ein block, inline, inline-block, table, table-row, table-cell, list-item, oder was auch immer!
Jedes dieser Elemente hat sehr unterschiedliche Auswirkungen auf das Layout, und es gibt keine vernünftige Möglichkeit, sie zu animieren oder reibungslos zu übergehen (stellen Sie sich beispielsweise einen reibungslosen Übergang von blocknach inlineoder umgekehrt vor!).

Aus diesem Grund werden Übergänge deaktiviert, wenn sich die Anzeige ändert (auch wenn die Änderung von oder nach erfolgt none- dies noneist nicht nur Unsichtbarkeit, sondern ein eigener Element-Rendering-Modus, der überhaupt kein Rendering bedeutet!).

Joel_MMCC
quelle
8
So gut die obigen Lösungen auch sein mögen, es war sehr befriedigend, eine vernünftige Erklärung dafür zu erhalten, warum Übergänge nicht für Anzeigeattribute gelten.
kqr
8
Ich stimme dir nicht zu. Es könnte durchaus Sinn machen. Wenn display: none to display: block sofort zu Beginn des Übergangs aufgetreten ist, wäre das großartig. Und für den Rückübergang wäre es perfekt, wenn es von Anzeige zu Block gehen würde: Keine direkt am Ende des Übergangs.
Curtis Yallop
2
Wenn Sie sich nicht vorstellen können, wie eine Animation von einem Punkt zu einem Rechteck aussieht, haben Sie Probleme. Ein Übergang von der Belegung ohne Leerzeichen zur Belegung eines rechteckigen Bereichs ist SEHR offensichtlich. Sie tun dies jedes Mal, wenn Sie ein Rechteck wie bei jeder Anwendung mit der Maus herausziehen. Infolge dieses Fehlers gibt es so viele Hacks mit maximaler Höhe und negativen Rändern, dass es lächerlich ist. Das einzige, was funktioniert, ist das Zwischenspeichern der "realen" Höhe und das anschließende Animieren von Null auf den zwischengespeicherten Wert mit JavaScript. Traurig.
Triynko
2
Tryniko: display: none ändert die Größe des Elements nicht in ein Rechteck von 0 x 0 - es entfernt es aus dem DOM. Sie können von einem Rechteck zu einem Punkt animieren, indem Sie die Eigenschaften width und height auf Null animieren. Anschließend fließen die anderen Elemente um das Rechteck herum, als hätte es 'display: none', aber das Attribut 'display' bleibt 'block'. Das Element befindet sich noch im DOM. Das Konzept der Animation zwischen Anzeige: Block und Anzeige: Keine ist lächerlich: Es gibt keine Zwischenzustände. Ein Element ist entweder im DOM vorhanden oder nicht, egal wie klein oder unsichtbar es ist.
Steve Thorpe
1
Es ist nicht lächerlich, diskrete Eigenschaften zu animieren. Diskrete Eigenschaften wie displaykönnen nicht wie andere Eigenschaften reibungslos übertragen werden, aber das bedeutet nicht, dass das Timing nicht wichtig ist. Es ist sehr wichtig zu kontrollieren, wann der Übergang von disply:blockzu stattfindet display:none. Genau wie @CurtisYallop es beschrieben hat. Wenn ich aus , um den Übergang will opacity:1zu opacity:0und dann Wechsel display:blockzu , display:noneich soll es tun können.
Jens
56

Anstelle von Rückrufen, die in CSS nicht vorhanden sind, können wir transition-delayEigenschaften verwenden.

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

Also, was ist hier los?

  1. Wenn eine visibleKlasse hinzugefügt wird, starten beide heightund opacitystarten die Animation ohne Verzögerung (0 ms), benötigen jedoch height0 ms, um die Animation abzuschließen (entspricht display: block) und opacity600 ms.

  2. Wenn die visibleKlasse entfernt wird, wird opacitydie Animation gestartet (0 ms Verzögerung, 400 ms Dauer) und die Höhe wartet 400 ms. Erst dann (0 ms) wird der Anfangswert wiederhergestellt (entspricht display: nonedem Animationsrückruf).

Beachten Sie, dass dieser Ansatz besser ist als der, der verwendet wird visibility. In solchen Fällen nimmt das Element immer noch den Platz auf der Seite ein und ist nicht immer geeignet.

Weitere Beispiele finden Sie in diesem Artikel .

Webars
quelle
8
überrascht, dass dies nicht mehr positive Stimmen hat - diese clevere Lösung funktioniert irgendwie perfekt.
Fanfare
3
Es funktioniert nur, mit height:100%denen das Layout in einigen Fällen zerstört werden kann. Tolle Lösung, wenn das kein Problem ist. Eine der wenigen bidirektional arbeitenden.
Fabian von Ellerts
Das ist toll! In meinem Fall konnte ich es noch weiter vereinfachen, da ich wollte, dass die Ausblendanimationszeit mit der Einblendzeit übereinstimmt. Anstatt zu benutzen transition: height 0ms 0ms, opacity 600ms 0ms, habe ich nur benutzt transition-delay: 0s.
Jacob Lockard
52

display ist keine der Eigenschaften, auf die der Übergang wirkt.

Unter Animierbare CSS-Eigenschaften finden Sie eine Liste der CSS-Eigenschaften, auf die Übergänge angewendet werden können. Siehe CSS Werte und Einheiten des Moduls 4, Kombinieren Werte: Interpolation, Addition, und Akkumulation , wie sie interpoliert werden.

Bis zu CSS 3 wurde in 9.1 aufgeführt. Eigenschaften aus CSS (schließen Sie einfach das Warn-Popup)

Ich habe auch versucht, Höhe zu verwenden, aber das ist kläglich gescheitert.

Das letzte Mal, als ich dies tun musste, habe ich max-heightstattdessen eine animierbare Eigenschaft verwendet (obwohl es ein bisschen wie ein Hack war, hat es funktioniert), aber Vorsicht, es kann für komplexe Seiten oder Benutzer mit Low-End-Mobilgeräten sehr ruckelig sein Geräte.

Robocat
quelle
Der Link verweist nicht mehr direkt auf den Abschnitt mit den animierbaren Eigenschaften.
Andrew Lam
1
@ AndrewLam behoben. Vielen Dank.
Robocat
34

Sie können der Blockeigenschaft jetzt eine benutzerdefinierte Animation hinzufügen.

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

Demo

In dieser Demo wechselt das Untermenü von display:nonezu display:blockund kann immer noch ausgeblendet werden.

Manish Pradhan
quelle
Sollte myfirstsein showNavhier? Und was ist mit Firefox? Leider kann ich auf der von Ihnen erwähnten Demoseite nichts Ähnliches finden.
Sebastian vom Meer
Danke @SebastianG. Ich habe die Korrektur vorgenommen und oben einige weitere Informationen hinzugefügt.
Manish Pradhan
@Sebastian vom Meer: Ältere Firefox-Versionen benötigen das Herstellerpräfix "-moz-", siehe bearbeiteten Code
Herr_Schwabullek
23
Sofern mir nichts fehlt, zeigt der "Demo" -Link keinen Untermenüübergang mehr an.
Realistisch
1
Der richtige Übergang für etwas, das keinen Platz einnimmt (wie dies bei display: none der Fall ist), zu etwas, das Platz einnimmt (display: block), ist eine Erweiterung der Dimensionen, kein Einblenden. Wenn es sich um eine versteckte Sichtbarkeit handelt (die Platz einnimmt, aber nicht sichtbar ist), bleibt die Größe gleich und ein Einblenden ist angemessen. Keine dieser Antworten löst das Problem.
Triynko
21

Laut W3C Working Draft ist der 19. November 2013 display keine animierbare Eigenschaft . Zum Glück visibilityist animierbar. Sie können den Übergang mit einem Übergang der Deckkraft ( JSFiddle ) verketten :

  • 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 zum Testen:

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

Beachten Sie, dass der Link visibility: hiddenanklickbar bleibt , wenn Sie ihn nur ohne Einstellung transparent machen .

Feklee
quelle
1
Ich sehe überhaupt keinen Übergang im jsfiddle-Beispiel
Gino
@ Gino Ich habe es behoben, indem ich zu gewechselt 0habe 0s. Anscheinend hat der Browser, den ich zum Testen verwendet habe, in der Vergangenheit einheitlose Nullzeiten unterstützt. Zeiten ohne Einheit sind jedoch nicht Teil der W3C-Kandidatenempfehlung vom 29. September 2016 .
Feklee
Dies sollte mehr positiv bewertet werden. Ich fand es eine der besten Lösungen.
Arthur Tarasov
Die Verwendung von Verzögerung ist nur die beste Logik, um zu verstehen, wie dies funktioniert. Animieren und verstecken. Ausblenden und animieren. Perfekte Lösung für mich
Bruno Pitteli Gonçalves
15

Bearbeiten: Anzeige keine wird in diesem Beispiel nicht angewendet.

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

Was oben passiert, ist, dass 99% der Animationsanzeige so eingestellt sind, dass sie blockiert, während die Deckkraft ausgeblendet wird. Im letzten Moment wird die Anzeigeeigenschaft auf none gesetzt.

Und das Wichtigste ist, das letzte Bild nach dem Ende der Animation im Animationsfüllmodus beizubehalten: vorwärts

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

Hier sind zwei Beispiele: https://jsfiddle.net/qwnz9tqg/3/

Pawel
quelle
mit dieser Lösung display: nonefunktioniert dann nicht?
Bart Calixto
Sollte "Animations-Füll-Modus: vorwärts" sein, nicht "vorwärts"
Alex
Bearbeitungen müssen aus sechs Zeichen bestehen und ich kann nur vorschlagen, sie zu bearbeiten, daher der Kommentar
Alex
1
@ Alex Ok. Tippfehler behoben. Interessant ist, dass meine Antwort nicht einmal wie erwartet funktioniert, aber es ist logisch zu glauben, dass dies der Fall ist. Ich werde sie so lange beibehalten, bis die Browser sie unterstützen.
Pawel
3
Wie Sie in dieser Geige mit Cursorn sehen können display: none, wird, nie wirklich implementiert. jsfiddle.net/3e6sduqh
robstarbuck
14

Mein netter JavaScript-Trick besteht darin, das gesamte Szenario in zwei verschiedene Funktionen zu unterteilen !

Zur Vorbereitung wird eine globale Variable deklariert und ein Ereignishandler definiert:

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

Wenn ich dann ein Element verstecke, verwende ich so etwas:

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

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

Um das Element wieder zu sehen, mache ich so etwas:

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

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

Es funktioniert soweit!

Sasa Milenkovic
quelle
Dies funktioniert aufgrund der Zeitverzögerung und nicht, weil sich die Javascript-Befehle in separaten Funktionen befinden. Zeitverzögerungen scheinen in vielen Fällen eine gute Lösung zu sein :)
10

Ich position: fixedbin heute darauf gestoßen , mit einem Modal, das ich wiederverwendete. Ich konnte es nicht behalten display: noneund dann animieren, da es gerade in Erscheinung trat und z-index(negative Werte usw.) auch seltsame Dinge tat.

Ich habe auch ein height: 0to verwendet height: 100%, aber es hat nur funktioniert, als das Modal erschien. Dies ist das gleiche, als ob Sie verwendet haben left: -100%oder so.

Dann fiel mir auf, dass es eine einfache Antwort gab. Et voila:

Erstens dein verstecktes Modal. Beachten Sie das heightist 0und überprüfen Sie die heightDeklaration in Übergängen ... es hat ein 500ms, das länger ist als mein opacityÜbergang . Denken Sie daran, dass dies Auswirkungen auf den ausgehenden Ausblendübergang hat: Zurücksetzen des Modals in seinen Standardzustand.

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

Zweitens Ihr sichtbares Modal. Angenommen, Sie setzen ein .modal-activeauf body. Jetzt heightist das 100%, und mein Übergang hat sich auch geändert. Ich möchte das heightsofort geändert werden, und das opacityzu übernehmen 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;
}

Das war's, es funktioniert wie ein Zauber.

Hotmeteor
quelle
Upvoting für Ihren Stil der Ausrichtung der vom Hersteller vorangestellten Eigenschaften 👍
George Green
9

Ausgehend von einigen dieser Antworten und einigen anderen Vorschlägen eignet sich das Folgende hervorragend für Hover-Menüs (ich verwende dies  speziell für Bootstrap 3):

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

Sie können auch heightanstelle von verwenden, max-heightwenn Sie beide Werte angeben, da height:autodies mit transitions nicht zulässig ist . Der Schwebewert von max-heightmuss größer sein als der heightdes Menüs.

Edyn
quelle
3
Es ist ein schöner Trick, aber es gibt ein Manko. Die Übergangszeit hängt von der Höhe ab. Wenn es mehrere Menüs mit variabler Höhe gibt, werden Elemente mit einer Höhe näher an der maximalen Höhe gut animiert. Die kürzeren werden jedoch zu schnell animiert, was zu einer inkonsistenten Erfahrung führt.
Benutzer
8

Ich habe einen besseren Weg für dieses Problem gefunden. Sie können CSS-Animation verwenden und Ihren fantastischen Effekt für das Anzeigen von Elementen erzielen.

    .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
quelle
Vielen Dank für diesen nützlichen Tipp. Das funktioniert perfekt.
Sedat Kumcu
6

Ich bin mehrmals auf dieses Problem gestoßen und habe mich jetzt einfach für Folgendes entschieden:

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

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

Durch Hinzufügen der Klasse block--invisiblekönnen nicht alle Elemente angeklickt werden, aber alle dahinter stehenden Elemente werden aufgrund pointer-events:nonedessen von allen gängigen Browsern unterstützt (kein IE <11).

DominikAngerer
quelle
Können Sie dies bitte in ein Beispiel einfügen?
GarethAS
1
Dies funktioniert gut, sollte aber beachtet werden, dass
Zeigerereignisse
Hinweis für IE unter 11 hinzugefügt
DominikAngerer
Wenn Sie dieses Element über alles haben müssen (zum Beispiel ein Menü), ist dies ehrlich gesagt der sauberste Weg, dies jetzt zu tun, da die Unterstützung für 2019 solide istpointer-events
Josh Davenport
5

Wechseln Sie overflow:hiddenzu overflow:visible. Es funktioniert besser. Ich benutze so:

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

visibleist besser, weil overflow:hiddengenau wie ein handelndisplay:none .

Jesus
quelle
Dieser war das Ticket für mich. Vielen Dank!
Dan Loewenherz
5

JavaScript ist nicht erforderlich, und es wird keine unglaublich große maximale Höhe benötigt. Legen Sie stattdessen max-heightIhre Textelemente fest und verwenden Sie eine relative Schriftarteinheit wie remoder em. Auf diese Weise können Sie eine maximale Höhe festlegen, die größer als Ihr Container ist, und gleichzeitig eine Verzögerung oder ein "Knallen" vermeiden, wenn das Menü geschlossen wird:

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
}

Ein Beispiel finden Sie hier: http://codepen.io/mindfullsilence/pen/DtzjE

Achtsamkeit
quelle
Ähnlich wie bei diesem können Sie die Zeilenhöhe für Ihren Text festlegen und in Null umwandeln. Wenn nur Text enthalten ist, wird der Container ausgeblendet.
Vicmortelmans
Warum so wenige Stimmen? Dies ist eine wirklich gute Antwort und möglicherweise die, die ich benutze.
Mwilcox
@mwilcox Da eine feste Höhe verwendet wird, was bei der Arbeit mit dynamischen Inhalten schlecht ist (eine geschätzte Höhe sogar). Und es ist nur für Textinhalte nützlich.
Fabian von Ellerts
5

Nachdem die akzeptierte Antwort von Guillermo geschrieben wurde, hat die CSS-Übergangsspezifikation vom 03.04.2012 das Verhalten des Sichtbarkeitsübergangs geändert. Jetzt ist es möglich, dieses Problem auf kürzere Weise ohne Verwendung einer Übergangsverzögerung zu lösen :

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

Die für beide Übergänge angegebene Laufzeit sollte normalerweise identisch sein (obwohl eine etwas längere Sichtbarkeit kein Problem darstellt).

Eine laufende Version finden Sie in meinem Blogbeitrag CSS Transition Visibility .

Schreiben Sie den Titel der Frage "Übergänge auf dem Display: Eigenschaft" und als Antwort auf Kommentare von Rui Marques und Josh auf die akzeptierte Antwort:

Diese Lösung funktioniert in Fällen, in denen es irrelevant ist, ob die Anzeige- oder Sichtbarkeitseigenschaft verwendet wird (wie dies in dieser Frage wahrscheinlich der Fall war).

Das Element wird nicht vollständig entfernt display:none, sondern nur unsichtbar gemacht. Es bleibt jedoch im Dokumentfluss und beeinflusst die Position der folgenden Elemente.

Übergänge, bei denen das Element ähnlich wie vollständig vollständig entfernt wird, display:nonekönnen mithilfe der Höhe (wie in anderen Antworten und Kommentaren angegeben), der maximalen Höhe oder des oberen oder unteren Randbereichs durchgeführt werden. Siehe auch Wie kann ich die Übergangshöhe: 0; zur Höhe: auto; mit CSS? und mein Blogbeitrag Problemumgehungen für CSS-Übergänge in den Eigenschaften Anzeige und Höhe .

Antwort auf einen Kommentar von GeorgeMillo: Beide Eigenschaften und beide Übergänge werden benötigt: Die Opazitätseigenschaft wird verwendet, um eine Ein- und Ausblendanimation zu erstellen, und die Sichtbarkeitseigenschaft, um zu vermeiden, dass das Element immer noch auf Mausereignisse reagiert. Für die Deckkraft des visuellen Effekts und die Sichtbarkeit sind Übergänge erforderlich, um das Ausblenden zu verzögern, bis das Ausblenden abgeschlossen ist.

Helmut Emmelmann
quelle
4

Ich fand schließlich eine Lösung für mich, durch die Kombination opacitymit position absolute(nicht Raum zu besetzen , wenn versteckt).

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

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

Ich vermute, dass jeder, der gerade CSS-Übergänge startet, schnell feststellt, dass sie nicht funktionieren, wenn Sie gleichzeitig die Anzeigeeigenschaft (block / none) ändern. Eine Problemumgehung, die noch nicht erwähnt wurde, besteht darin, dass Sie display:block/nonedas Element weiterhin zum Ausblenden / Anzeigen verwenden können, seine Deckkraft jedoch auf 0 setzen, sodass es auch dann display:blocknoch unsichtbar ist , wenn es angezeigt wird.

Fügen Sie dann zum Einblenden eine weitere CSS-Klasse wie "Ein" hinzu, die die Deckkraft auf 1 setzt und den Übergang für die Deckkraft definiert. Wie Sie sich vielleicht vorgestellt haben, müssen Sie JavaScript verwenden, um diese "on" -Klasse zum Element hinzuzufügen, aber zumindest verwenden Sie immer noch CSS für den eigentlichen Übergang.

PS Wenn Sie sich in einer Situation befinden, in der Sie beides tun display:blockund gleichzeitig die Klasse "on" hinzufügen müssen, verschieben Sie diese mithilfe von setTimeout. Andernfalls sieht der Browser nur beide Dinge gleichzeitig und deaktiviert den Übergang.

Larry Gerndt
quelle
Großartig, danke! Ich habe eine andere Antwort mit einem Beispiel geschrieben, mit dem tatsächlich funktioniert display:none.
Mojuba
4

Es ist so einfach wie das folgende :)

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

Lass es verblassen und mach es dann height 0;. Stellen Sie außerdem sicher, dass Sie Forwards verwenden, damit es im Endzustand bleibt.

Veljko Simakovic
quelle
Dies würde sofort zurückgesetzt, wenn die Klasse entfernt wird, so dass es keine gute Idee ist
Sean T
2

Diese Lösung ist hervorragend kompatibel und ich habe sie noch nicht gesehen:

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

Erläuterung : Es wird der visibility: hiddenTrick verwendet (der in einem Schritt mit "Anzeigen und Animieren" kompatibel ist), aber es wird die Kombination verwendet position: absolute; z-index: -1; pointer-events: none;, um sicherzustellen, dass der versteckte Container keinen Platz beansprucht und nicht auf Benutzerinteraktionen reagiert .

Christophe Marois
quelle
1
Aber der Wechsel von positionStill wird das Element ruckeln lassen, nein?
Arsylum
Natürlich: position: absolutebedeutet, dass das Element keinen Platz einnimmt, wie in der Erklärung beschrieben. Wenn es zu wechselt position: staticund angezeigt wird, nimmt es wie ein normales Element Platz ein, worum es bei dieser Frage geht. Ich schlage vor, Sie versuchen es!
Christophe Marois
2
Ich tat. Aber wenn ich richtig verstehe, ging es um Übergänge . Wie bei "glatten Animationen".
Arsylum
2

Sie können dies so erreichen, wie Sie es erwartet haben - mithilfe der Anzeige -, aber Sie müssen den Browser drosseln, damit es funktioniert, entweder mit Javascript oder wie andere einen ausgefallenen Trick mit einem Tag in einem anderen vorgeschlagen haben. Das innere Tag ist mir egal, da es CSS und Dimensionen weiter verkompliziert. Hier ist die Javascript-Lösung:

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

Beginnend mit einer Box wie:

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

Eine versteckte Kiste.

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

Wir werden einen Trick verwenden, der in einem verwandten Q / A gefunden wird, und OffsetHeight überprüfen, um den Browser sofort zu drosseln:

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

Zunächst eine Bibliothek, die den obigen Trick formalisiert:

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

Als nächstes werden wir es verwenden, um eine Box zu enthüllen und sie einzublenden:

$('#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 });
});

Dadurch wird die Box ein- und ausgeblendet. Deaktiviert also .noTrnsn()Übergänge, dann entfernen wir die hiddenKlasse, die displayvon noneihrer Standardeinstellung wechselt block. Wir setzen dann die Deckkraft auf 0, um uns auf das Einblenden vorzubereiten. Nachdem wir die Bühne eingerichtet haben, schalten wir die Übergänge mit wieder ein .resumeTrnsn(). Beginnen Sie den Übergang, indem Sie die Deckkraft auf 1 setzen.

Ohne die Bibliothek hätten sowohl die Änderung der Anzeige als auch die Änderung der Deckkraft zu unerwünschten Ergebnissen geführt. Wenn wir die Bibliotheksaufrufe einfach entfernen würden, würden wir überhaupt keine Übergänge erhalten.

Beachten Sie, dass die Anzeige am Ende der Ausblendanimation nicht erneut auf "Keine" gesetzt wird. Wir können aber schicker werden. Lassen Sie uns dies mit einem tun, der einblendet und von 0 an an Höhe zunimmt.

Schick!

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

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

Wir wechseln jetzt sowohl Höhe als auch Deckkraft. Beachten Sie, dass wir keine Höhe einstellen, was bedeutet, dass dies die Standardeinstellung ist auto. Herkömmlicherweise kann dies nicht geändert werden. Wenn Sie von Auto zu einem Pixelwert (wie 0) wechseln, erhalten Sie keinen Übergang. Wir werden das mit der Bibliothek und einer weiteren Bibliotheksmethode umgehen:

$.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();
    });
};

Dies ist eine praktische Methode, mit der wir an der vorhandenen fx / animation-Warteschlange von jQuery teilnehmen können, ohne das Animationsframework zu benötigen, das jetzt in jQuery 3.x ausgeschlossen ist. Ich werde nicht erklären, wie jQuery funktioniert, aber es reicht zu sagen, dass die von jQuery bereitgestellten .queue()und .stop()Installationen uns dabei helfen, zu verhindern, dass unsere Animationen aufeinander treten.

Animieren wir den Slide-Down-Effekt.

$('#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');
        });
    }
});

Dieser Code beginnt mit der Überprüfung #boxund ob er derzeit ausgeblendet ist, indem er seine Klasse überprüft. Mit dem wait()Bibliotheksaufruf wird jedoch mehr erreicht , indem die hiddenKlasse am Ende der Slideout- / Fade-Animation hinzugefügt wird, die Sie erwarten würden, wenn sie tatsächlich ausgeblendet ist - etwas, das das obige einfachere Beispiel nicht kann. Dies ermöglicht auch das wiederholte Ein- und Ausblenden des Elements, was im vorherigen Beispiel ein Fehler war, da die versteckte Klasse nie wiederhergestellt wurde.

Sie können auch sehen, dass CSS- und Klassenänderungen aufgerufen werden, .noTrnsn()um im Allgemeinen die Bühne für Animationen festzulegen, einschließlich Messungen, z. B. Messen der endgültigen Höhe, #boxohne dies dem Benutzer zu zeigen, bevor Sie aufrufen .resumeTrnsn(), und Animieren von diesem vollständigen Satz Stufe zu seinem Ziel CSS-Werte.

Alte Antwort

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

Sie können den Übergang per Mausklick mit:

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

Das CSS ist das, was Sie vermuten würden:

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

Der Schlüssel drosselt die Anzeigeeigenschaft. Wenn Sie die versteckte Klasse entfernen und dann 50 ms warten und dann den Übergang über die hinzugefügte Klasse starten, wird sie angezeigt und dann wie gewünscht erweitert, anstatt nur ohne Animation auf den Bildschirm zu blättern. Ähnliches geschieht in die andere Richtung, außer dass wir warten, bis die Animation beendet ist, bevor wir versteckt anwenden.

Hinweis: Ich missbrauche .animate(maxWidth)hier, um setTimeoutRennbedingungen zu vermeiden . setTimeoutEs ist schnell, versteckte Fehler einzuführen, wenn Sie oder jemand anderes Code aufnimmt, ohne es zu wissen. .animate()kann leicht mit getötet werden .stop(). Ich benutze es nur, um eine Verzögerung von 50 ms oder 2000 ms in die Standard-FX-Warteschlange zu setzen, wo es von anderen Codierern, die darauf aufbauen, leicht zu finden / aufzulösen ist.

Chris Moschini
quelle
1

Ich hatte ein ähnliches Problem, auf das ich keine Antwort finden konnte. Einige Google-Suchanfragen führten mich später hierher. Da ich nicht die einfache Antwort gefunden hatte, auf die ich gehofft hatte, stieß ich auf eine Lösung, die sowohl elegant als auch effektiv ist.

Es stellt sich heraus, dass die visibilityCSS-Eigenschaft einen Wert hat, collapseder im Allgemeinen für Tabellenelemente verwendet wird. Wenn es jedoch für andere Elemente verwendet wird, werden sie effektiv als ausgeblendet dargestellt , ähnlich wie display: hiddenmit der zusätzlichen Fähigkeit, dass das Element keinen Platz einnimmt und Sie das betreffende Element dennoch animieren können.

Unten finden Sie ein einfaches Beispiel dafür in Aktion.

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
quelle
1

Die einfachste universelle Lösung für das Problem lautet: Sie können es gerne display:nonein Ihrem CSS angeben. Sie müssen es jedoch blockmithilfe von JavaScript in (oder was auch immer) ändern , und dann müssen Sie Ihrem betreffenden Element eine Klasse hinzufügen, die tatsächlich vorhanden ist führt den Übergang mit setTimeout () durch . Das ist alles.

Dh:

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

Dies wurde in den neuesten vernünftigen Browsern getestet. Offensichtlich sollte es in Internet Explorer 9 oder früher nicht funktionieren.

Mojuba
quelle
1

Ich denke, SalmanPK hat die naheliegendste Antwort. Mit den folgenden CSS-Animationen wird ein Element ein- oder ausgeblendet. Die Anzeigeeigenschaft wird jedoch nicht reibungslos animiert, sondern nur die Deckkraft.

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

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

Wenn Sie das Element animieren möchten, das vom Anzeigeblock zum Anzeigeblock wechselt, kann ich nicht sehen, dass dies derzeit nur mit CSS möglich ist. Sie müssen die Höhe ermitteln und eine CSS-Animation verwenden, um die Höhe zu verringern. Dies ist mit CSS möglich, wie im folgenden Beispiel gezeigt. Es wäre jedoch schwierig, die genauen Höhenwerte zu kennen, die Sie zum Animieren eines Elements benötigen.

jsFiddle Beispiel

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
quelle
1

Sie können dies mit Übergangsereignissen tun, sodass Sie zwei CSS-Klassen für den Übergang erstellen, von denen eine die Animation und die andere den Status "Keine Anzeige" enthält. Und Sie wechseln sie, nachdem die Animation beendet ist? In meinem Fall kann ich die Divs erneut anzeigen, wenn ich eine Taste drücke, und beide Klassen entfernen.

Probieren Sie das folgende Snippet aus ...

$(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
quelle
0

Wenn Sie Ihre Klassen mit jQuery festlegen, funktioniert dies zu 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>

Natürlich können Sie auch nur jQuery .fadeIn()und .fadeOut()Funktionen verwenden, aber der Vorteil des Festlegens von Klassen besteht darin, dass Sie zu einem anderen Anzeigewert als block(wie bei .fadeIn()und .fadeOut()) standardmäßig wechseln möchten .

Hier wechsle ich zur Anzeige flexmit einem schönen Fade-Effekt.

G STAR
quelle
0

Anstatt zu verwenden, können displaySie das Element "außerhalb des Bildschirms" speichern, bis Sie es benötigen, und dann seine Position an der gewünschten Stelle festlegen und gleichzeitig transformieren. Dies wirft jedoch eine ganze Reihe anderer Designprobleme auf, sodass Ihr Kilometerstand variieren kann.

Sie möchten es wahrscheinlich displaysowieso nicht verwenden , da Sie möchten, dass der Inhalt für Bildschirmleser zugänglich ist, die größtenteils versuchen, die Regeln für die Sichtbarkeit einzuhalten - dh wenn er für das Auge nicht sichtbar sein sollte, ist dies der Fall wird dem Agenten nicht als Inhalt angezeigt.

Peter Mortensen
quelle
0

Sie können einfach die CSS- Sichtbarkeit verwenden : versteckt / sichtbar anstelle von Anzeige : keine / Block

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
quelle
5
Dies reserviert jedoch den Platz und hinterlässt ein leeres Loch. Wenn Sie ein Leerzeichen reduzieren möchten, müssen Sie die Höhe oder eine andere Eigenschaft animieren.
Marcy Sutton
0

Ich habe ein Open-Source-Skelettprojekt namens Toggle Display Animate gestartet .

Mit diesem Skeleton-Helfer können Sie das Ein- und Ausblenden von jQuery problemlos nachahmen, jedoch mit CSS 3-Übergangsanimationen.

Es werden Klassenumschaltungen verwendet, sodass Sie neben der Anzeige auch beliebige CSS-Methoden für Elemente verwenden können: none | block | table | inline usw. sowie andere alternative Verwendungszwecke, die sich ausdenken lassen.

Der Hauptentwurfszweck ist das Umschalten von Elementen und es wird ein Wiederherstellungszustand unterstützt, bei dem Sie durch Ausblenden des Objekts Ihren Keyframe in umgekehrter Reihenfolge ausführen oder eine alternative Animation zum Ausblenden des Elements abspielen können.

Der größte Teil des Markups für das Konzept, an dem ich arbeite, ist CSS, und es wird nur sehr wenig JavaScript verwendet.

Hier gibt es eine Demo: http://marcnewton.co.uk/projects/toggle-display-animate/

Marc
quelle