Przejścia na właściwości CSS display

Obecnie projektuję menu "mega rozwijane" CSS - w zasadzie zwykłe rozwijane menu tylko CSS, ale takie, które zawiera różne rodzaje treści.

W tej chwili wygląda na to, że przejścia CSS 3 nie mają zastosowania do właściwości "display" , tzn. nie można wykonać żadnego przejścia z display: none do display: block (ani żadnej kombinacji).

Czy istnieje sposób, aby menu drugiego poziomu z powyższego przykładu "zniknęło", gdy ktoś najedzie na jeden z najwyższych poziomów menu?

Wiem, że możesz używać przejść na właściwości visibility:, ale nie mogę wymyślić sposobu na efektywne wykorzystanie tego.

Próbowałem również używać wysokości, ale to po prostu nie powiodło się.

Jestem również świadomy, że osiągnięcie tego za pomocą JavaScript jest trywialne, ale chciałem rzucić sobie wyzwanie, aby użyć tylko CSS i myślę, że nadchodzę trochę za krótko.

Author: Ankit Kante, 2010-07-25

30 answers

Możesz połączyć dwa przejścia lub więcej, i visibility jest Tym razem przydatne.

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>

(nie zapomnij przedrostka vendor do Właściwości transition.)

Więcej szczegółów znajduje się w w tym artykule .

 1473
Author: Guillermo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 17:47:15

Musisz ukryć element w inny sposób, aby to zadziałało.

Osiągnąłem ten efekt, ustawiając oba <div> absolutnie i ustawiając Ukryty na opacity: 0.

Jeśli nawet przełączysz właściwość display z none na block, przejście na innych elementach nie nastąpi.

Aby to obejść, zawsze pozwól elementowi być display: block, ale Ukryj element, dostosowując dowolny z tych środków:

  1. Ustaw height na 0.
  2. Ustaw opacity na 0.
  3. umieść element poza ramką innego elementu, który ma overflow: hidden.

Jest prawdopodobnie więcej rozwiązań, ale nie możesz wykonać przejścia, jeśli przełączysz element na display: none. Na przykład możesz spróbować czegoś takiego:

div {
    display: none;
    transition: opacity 1s ease-out;
    opacity: 0;
}
div.active {
    opacity: 1;
    display: block;
}
Ale to zadziała. Z doświadczenia wiem, że to nic nie da.

Z tego powodu zawsze będziesz musiał zachować element display: block - ale można to obejść robiąc coś takiego:

div {
    transition: opacity 1s ease-out;
    opacity: 0;
    height: 0;
    overflow: hidden;
}
div.active {
    opacity: 1;
    height: auto;
}
 844
Author: Jim Jeffers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 18:06:05

W czasie tego postu wszystkie główne przeglądarki wyłączają przejścia CSS, jeśli spróbujesz zmienić właściwość display, ale animacje CSS nadal działają dobrze, więc możemy ich użyć jako obejścia.

Przykładowy kod (Możesz zastosować go odpowiednio do swojego menu) Demo:

Dodaj następujący CSS do swojego arkusza stylów:

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

Następnie zastosuj animację fadeIn do dziecka po najechaniu kursorem na rodzica (i oczywiście Ustaw display: block):

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

Aktualizacja 2019-metoda, która obsługuje również fading out:

(wymagany jest jakiś kod JavaScript)

// 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>
 304
Author: Salman von Abbas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 18:13:08

Podejrzewam, że powód , że przejścia są wyłączone, jeśli display jest zmieniony, wynika z tego, co faktycznie robi wyświetlacz. Nie zmienia niczego, co mogłoby być płynnie animowane.

display: none; i visibility: hidden; są dwie całkowicie różne rzeczy.
Oba mają efekt uczynienia elementu niewidzialnym, ale z {[2] }nadal jest renderowany w układzie, ale po prostu nie widocznie tak.
Ukryty element wciąż zajmuje miejsce, i jest nadal renderowany w linii lub jako blok lub block-inline lub tabela lub cokolwiek display element każe mu renderować jako, i zajmuje odpowiednio miejsce.
Inne elementy nie } automatycznie poruszają się, aby zająć tę przestrzeń. Ukryty element po prostu nie renderuje swoich rzeczywistych pikseli na wyjściu.

display: none z drugiej strony faktycznie uniemożliwia element z renderowania całkowicie.
Nie zajmuje żadnej przestrzeni układu.
Inne elementy to zajmowałoby część lub całość przestrzeni zajmowanej przez ten element, teraz dostosowując się do zajmowania tej przestrzeni, tak jakby element po prostu w ogóle nie istniał.

display to nie tylko kolejny atrybut wizualny.
Określa cały tryb renderowania elementu, np. czy jest block, inline, inline-block, table, table-row, table-cell, list-item, albo cokolwiek!
Każdy z nich ma bardzo różne konsekwencje dotyczące układu i nie byłoby rozsądnego sposobu animowania lub płynnego przenieś je (spróbuj wyobrazić sobie płynne przejście z block do inline lub odwrotnie, na przykład!).

Dlatego przejścia są wyłączone, jeśli wyświetlanie się zmienia (nawet jeśli zmiana jest na lub z none - none to nie tylko niewidzialność, to własny tryb renderowania elementów, który oznacza brak renderowania!).

 90
Author: Joel_MMCC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-24 07:09:51

Zamiast wywołań zwrotnych, które nie istnieją w CSS, możemy użyć właściwości 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;
}
Co tu się dzieje?
  1. Po dodaniu klasy visible, zarówno height, jak i opacity rozpoczynają animację bez opóźnienia (0 ms), chociaż height trwa 0 ms, aby ukończyć animację (odpowiednik display: block), A opacity zajmuje 600 ms.

  2. Po usunięciu klasy visible, opacity rozpoczyna animację (opóźnienie 0 ms, Czas trwania 400 ms), a wysokość czeka 400 ms i dopiero wtedy natychmiast (0 ms) przywraca wartość początkową (odpowiednik display: none w wywołaniu zwrotnym animacji).

Uwaga, to podejście jest lepsze niż te z użyciem visibility. W takich przypadkach element nadal zajmuje miejsce na stronie i nie zawsze jest odpowiedni.

Więcej przykładów można znaleźć w w tym artykule .

 84
Author: Webars,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 20:01:55

display nie jest jedną z właściwości, na których działa Przejście.

Zobacz animowane właściwości CSS dla listy właściwości CSS, które mogą mieć zastosowane do nich przejścia. Zobacz też CSS Values and Units Module Level 4, Combining Values: Interpolation, Addition, and Accumulation za ich interpolację.

Do CSS 3 został wymieniony w 9.1. Właściwości z CSS (wystarczy zamknąć okienko ostrzegawcze)

I ' ve próbowałem również używać wysokości, ale to po prostu nie powiodło się.

Ostatni raz musiałem to zrobić, użyłem max-height zamiast tego, co jest właściwością do animowania (chociaż było to trochę włamanie, zadziałało), ale uważaj, że może być bardzo drażliwy dla złożonych stron lub użytkowników z niskonakładowymi urządzeniami mobilnymi.

 57
Author: robocat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 18:10:46

Możesz teraz dodać własną animację do właściwości 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;
}

Demo

W tym demo pod-menu zmienia się z display:none na display:block i nadal udaje się zniknąć.

 35
Author: Manish Pradhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 18:48:46

Zgodnie z W3C Working Draft 19 listopada 2013 display nie jest własnością animowaną . Na szczęście, {[4] } jest animowana. Możesz połączyć jego przejście z przejściem nieprzezroczystości (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 do testowania:

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

Zauważ, że jeśli tylko sprawisz, że link będzie przezroczysty, bez ustawiania visibility: hidden, pozostanie klikalny.

 23
Author: feklee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-27 16:18:59

Znalazłem lepszy sposób na ten problem, możesz użyć animacji CSS i zrobić swój niesamowity efekt do wyświetlania przedmiotów.

.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)
     }
}
 22
Author: ThisIsWilliam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-05 12:42:48

Moją zgrabną sztuczką JavaScript jest rozdzielenie całego scenariusza na dwie różne funkcje !

Aby przygotować rzeczy, zadeklarowana jest jedna zmienna globalna i zdefiniowana jest jedna Obsługa zdarzenia:

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

Następnie, ukrywając element, używam czegoś takiego:

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

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

Za ponowne pojawienie się elementu, robię coś takiego:

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

function timeoutShow(){
  element.style.opacity = 1;
}
Jak na razie działa!
 16
Author: Sasa Milenkovic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-14 21:55:24

Edit: display none nie jest stosowane w tym przykładzie.

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

Powyżej dzieje się tak, że przez 99% wyświetlacza animacji jest ustawione na blokowanie, gdy krycie zanika. W ostatniej chwili właściwość display jest ustawiona na none.

I najważniejszym bitem jest zachowanie ostatniej klatki po zakończeniu animacji za pomocą animation-fill-mode: forwards

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

Oto dwa przykłady: https://jsfiddle.net/qwnz9tqg/3/

 16
Author: Pawel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-14 15:12:47

Wpadłem na to dzisiaj, z modalem, którego używałem ponownie. Nie mogłem go zatrzymać display: none, a następnie animować, ponieważ po prostu wskoczył do wyglądu i z-index (wartości ujemne itp.) robił dziwne rzeczy.

Używałem również height: 0 do height: 100%, ale działało tylko wtedy, gdy pojawił się modal. To jest to samo, jak gdybyś użył left: -100% lub czegoś takiego.

Wtedy dotarło do mnie, że istnieje prosta odpowiedź. Et voila:

Po pierwsze, Twój ukryty modal. Zwróć uwagę na height jest 0, i sprawdź deklarację height w przejściach... posiada 500ms, która jest dłuższa niż mojeopacity Przejście . Pamiętaj, że ma to wpływ na przechodzące Przejście fade-out: przywrócenie modalu do stanu domyślnego.

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

Po Drugie, Twój widoczny modal. Powiedzmy, że ustawiasz .modal-active na body. Teraz height jest 100% i moje przejście również się zmieniło. Chcę, aby height zostały natychmiast zmienione, a opacity wziąć 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;
}
To jest to, działa jak urok.
 12
Author: hotmeteor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-19 18:49:30

Biorąc pod uwagę kilka z tych odpowiedzi i kilka sugestii w innym miejscu, następujące działa świetnie dla menu hover (używam tego z Bootstrap 3, konkretnie):

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

Możesz również użyć height zamiast max-height, Jeśli podasz obie wartości, ponieważ height:auto nie jest dozwolone z transition s. wartość najazdu max-height musi być większa niż height z menu może być.

 10
Author: Edyn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 18:39:05

Zmień overflow:hidden na overflow:visible. To działa lepiej. Używam Tak:

#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 jest lepszy, ponieważ overflow:hidden działa dokładnie jak display:none.

 6
Author: jesus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-09 16:45:09

Natknąłem się na ten problem wiele razy i teraz po prostu poszedł z:

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

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

Poprzez dodanie klasy block--invisible całe elementy nie będą klikalne, ale wszystkie elementy za nią będą spowodowane pointer-events:none, który jest obsługiwany przez wszystkie główne przeglądarki (brak IE

 6
Author: DominikAngerer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-04 07:32:56

W końcu znalazłem rozwiązanie dla siebie, łącząc opacity z position absolute (aby nie zajmować przestrzeni, gdy jest ukryty).

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

.parent:hover .toggle {
  opacity: 1;
  position: static;
}
 5
Author: Damjan Pavlica,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-16 18:07:01

JavaScript nie jest wymagany, i nie jest potrzebna duża maksymalna wysokość. Zamiast tego Ustaw max-height na elementach tekstu i użyj jednostki względnej czcionki, takiej jak rem lub em. W ten sposób można ustawić maksymalną wysokość większą niż kontener, unikając opóźnienia lub" popping " po zamknięciu 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
}

Zobacz przykład tutaj: http://codepen.io/mindfullsilence/pen/DtzjE

 5
Author: mindfullsilence,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 18:46:48

Po napisaniu zaakceptowanej odpowiedzi od guillermo, CSS Specyfikacja przejścia z 2012-04-03 zmieniła zachowanie przejścia widoczności i Teraz możliwe jest rozwiązanie tego problemu w krótszy sposób , bez użycia transition-delay:

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

Czas wykonania określony dla obu przejść powinien być zazwyczaj identyczny (aczkolwiek nieco dłuższy czas na widoczność nie stanowi problemu).

Aby zobaczyć wersję uruchomioną, zobacz mój wpis na bloguCSS Widoczność Przejścia.

W. r.T. tytuł pytania "Transitions on the display: property" i w odpowiedzi na komentarze Rui Marques i Josha na zaakceptowaną ODPOWIEDŹ:

To rozwiązanie działa w przypadkach gdzie nie ma znaczenia, czy wyświetlacz lub używana jest właściwość visibility (Jak zapewne miało to miejsce w tym pytaniu).

Nie usunie całkowicie elementu jako display:none, tylko uczyni go niewidzialnym, ale nadal pozostaje w dokumencie przepływ i wpływa na położenie następujących elementów.

Przejścia, które całkowicie usuwają element podobny do display:none można wykonać za pomocą wysokości( jak wskazują inne odpowiedzi i komentarze), max-height, lub margin-top/bottom, ale Zobacz też Jak mogę przejść Wysokość: 0; do wysokości: auto; za pomocą CSS? i mój wpis na bloguobejścia dla przejść CSS we właściwościach wyświetlania i wysokości.

W odpowiedzi na komentarz od GeorgeMillo: Potrzebne są obie właściwości i obie przejścia: właściwość krycie służy do tworzenia animacji fade-in i fade-out oraz widoczności właściwość pozwalająca uniknąć reakcji elementu na mysz wydarzenia. Potrzebne są przejścia na krycie dla efektu wizualnego i na widoczność, aby opóźnić ukrywanie się do zakończenia zanikania.

 5
Author: Helmut Emmelmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 19:05:43

To jest tak proste jak poniżej:)

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

Niech zniknie, a potem niech zniknie height 0;. Upewnij się również, że używasz do przodu, aby pozostał w stanie końcowym.

 5
Author: vSimak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 20:03:57

Podejrzewam, że każdy, kto dopiero zaczyna CSS transitions szybko odkrywa, że nie działają, jeśli modyfikujesz właściwość display (blok/brak) w tym samym czasie. Obejście problemu, o którym jeszcze nie wspomniano, polega na tym, że można nadal używać display:block/none do ukrywania / pokazywania elementu, ale ustawić jego krycie na 0, aby nawet gdy jest display:block, nadal był niewidoczny.

Następnie, aby zniknąć, dodaj inną klasę CSS, taką jak "on", która ustawia krycie na 1 i definiuje przejście dla krycia. As you may wyobraź sobie, że będziesz musiał użyć JavaScript, aby dodać tę klasę " on " do elementu, ale przynajmniej nadal używasz CSS do rzeczywistego przejścia.

P. S. Jeśli znajdziesz się w sytuacji, w której musisz wykonać zarówno display:block, jak i dodać klasę "on", w tym samym czasie, odrocz tę ostatnią używając setTimeout. W przeciwnym razie przeglądarka widzi obie rzeczy naraz i wyłącza Przejście.

 4
Author: Larry Gerndt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 18:15:35

Możesz uruchomić to w naturalny sposób, jakiego oczekiwałeś-za pomocą display-ale musisz Dławić przeglądarkę, aby ją uruchomić, używając Javascript lub tak, jak inni zasugerowali wymyślną sztuczkę z jednym tagiem w innym. Nie dbam o wewnętrzny znacznik, ponieważ dodatkowo komplikuje CSS i wymiary, więc oto rozwiązanie Javascript: {]}

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

Zaczynając od PUDEŁKA Typu:

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

A hidden box.

div.hidden {
    display: none;
}
#box {
    transition: opacity 1s;
}
    
W związku z tym, że przeglądarka nie jest w pełni kompatybilna z innymi przeglądarkami, nie jest w pełni kompatybilna z innymi przeglądarkami.]}

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

Po pierwsze, biblioteka formalizująca powyższą sztuczkę:

$.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;
    });
};
Następnie użyjemy go do odsłonięcia pudełka i wyblaknięcia:]}
$('#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 });
});

To zanika pudełko w I Na Zewnątrz. Tak więc .noTrnsn() wyłącza przejścia, następnie usuwamy hidden klasę, która przerzuca display z none do jej default, block. Następnie ustawiamy krycie na 0, aby przygotować się do zanikania. Teraz, gdy już ustawiliśmy scenę, włączamy przejścia z powrotem za pomocą .resumeTrnsn(). Na koniec rozpocznij Przejście, ustawiając krycie na 1.

Bez biblioteki, zarówno zmiana na wyświetlacz, jak i zmiana na krycie przyniosłyby nam niepożądane rezultaty. Gdybyśmy po prostu usunęli wywołania biblioteki, nie otrzymalibyśmy żadnych przejść.

Zauważ, że powyższe nie ustawia wyświetlania na brak ponownie na końcu fadeout animacja. Ale możemy stać się bardziej fantazyjni. Zróbmy to z takim, który zanika i rośnie w wysokości od 0.

Fancy!

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

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

Przenosimy teraz zarówno wysokość, jak i nieprzezroczystość. Zauważ, że nie ustawiamy wysokości, co oznacza, że jest to wartość domyślna, auto. Konwencjonalnie nie można tego przejść-przejście z wartości auto do wartości piksela (np. Popracujemy nad tym z biblioteką i jeszcze jedna metoda biblioteczna:

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

Jest to wygodna metoda, która pozwala nam uczestniczyć w istniejącej kolejce fx/animacji jQuery, bez konieczności stosowania żadnego frameworka animacji, który jest teraz wykluczony w jQuery 3.x. Nie będę wyjaśniał, jak działa jQuery, ale wystarczy powiedzieć, że .queue() i .stop() hydraulika, którą zapewnia jQuery, pomagają nam zapobiegać wchodzeniu na siebie naszych animacji.

Animujmy efekt slide down.

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

Ten kod zaczyna się od sprawdzenia na #box i czy jest obecnie Ukryty, sprawdzając jego klasę. Ale to osiąga więcej za pomocą wywołania biblioteki wait(), dodając klasę hidden na końcu animacji slideout/fade, której można się spodziewać, jeśli jest ona faktycznie ukryta - coś, czego powyższy prostszy przykład nie mógłby zrobić. Dzieje się tak również, że umożliwia wyświetlanie / ukrywanie elementu w kółko, co było błędem w poprzednim przykładzie, ponieważ ukryta Klasa nigdy nie została przywrócona.

Możesz również zobaczyć CSS i klasę zmiany są wywoływane po .noTrnsn(), aby ogólnie ustawić scenę dla animacji, włączając w to pomiary, takie jak pomiar ostatecznej wysokości #box bez pokazywania tego użytkownikowi, przed wywołaniem .resumeTrnsn(), i animowanie go z tego w pełni ustawionego etapu do jego docelowych wartości CSS.

Stara Odpowiedź

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

Możesz mieć to przejście po kliknięciu za pomocą:

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

CSS jest tym, co zgadniesz:

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

The kluczem jest dławienie właściwości wyświetlania. Usuwając ukrytą klasę, A następnie czekając 50 ms, następnie rozpoczynając przejście przez dodaną klasę, sprawiamy, że pojawia się ona, a następnie rozwija się tak, jak chcieliśmy, zamiast po prostu przesuwać się na ekran bez żadnej animacji. Podobnie dzieje się w drugą stronę, z tym, że czekamy aż animacja się skończy przed zastosowaniem hidden.

Uwaga: nadużywam .animate(maxWidth) tutaj, aby uniknąć setTimeout warunków wyścigu. setTimeout jest szybkie wprowadzenie ukrytych błędów, gdy ty lub ktoś inny odbierasz nieświadomy tego Kod. .animate() można łatwo zabić .stop(). Po prostu używam go, aby umieścić opóźnienie 50 ms lub 2000 ms w standardowej kolejce fx, gdzie łatwo jest znaleźć / rozwiązać inne kodery budujące na tym.

 3
Author: Chris Moschini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Najprostszym uniwersalnym rozwiązaniem problemu jest: możesz określić display:none w swoim CSS, jednak będziesz musiał zmienić go na block (lub cokolwiek innego) za pomocą JavaScript, a następnie będziesz musiał dodać klasę do danego elementu, która faktycznie wykonuje Przejście za pomocą setTimeout(). To wszystko.

Tj.:

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

To zostało przetestowane w najnowszych przeglądarkach. Oczywiście nie powinno działać w Internet Explorer 9 lub wcześniej.

 2
Author: mojuba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 18:18:14

To rozwiązanie ma doskonałą kompatybilność, a jeszcze go nie widziałem:

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

Explanation : używa sztuczki visibility: hidden (która jest kompatybilna z" show-and-animate " w jednym kroku), ale używa kombinacji position: absolute; z-index: -1; pointer-events: none;, aby upewnić się, że ukryty kontener nie zajmuje miejsca i nie odpowiada na interakcje użytkownika.

 2
Author: Christophe Marois,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 19:08:54

Miałem podobny problem, na który nie mogłem znaleźć odpowiedzi. Kilka wyszukiwań Google doprowadziło mnie później tutaj. Biorąc pod uwagę, że nie znalazłem prostej odpowiedzi, na którą liczyłem, natknąłem się na rozwiązanie, które jest zarówno eleganckie, jak i skuteczne.

Okazuje się, że właściwość visibility CSS ma wartość collapse, która jest zwykle używana dla elementów tabeli. Jednak, jeśli zostanie użyty na innych elementach, będzie on skutecznie renderował je jako hidden , prawie tak samo jak display: hidden, ale z dodaną zdolnością, że element nie zajmuje żadnego miejsca i nadal można animować dany element.

Poniżej znajduje się prosty przykład tego w działaniu.

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
Author: Deadmano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-29 03:34:37

Myślę, że SalmanPK ma najbliższą odpowiedź. To nie blaknie element w lub na zewnątrz, z następujących animacji CSS. Jednak właściwość wyświetlanie nie animuje płynnie, a jedynie krycie.

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

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

Jeśli chcesz animować element przechodzący z display block do display none, nie widzę, że jest to obecnie możliwe tylko za pomocą CSS. Musisz uzyskać wysokość i użyć animacji CSS, aby zmniejszyć wysokość. Jest to możliwe w CSS, jak pokazano w poniższym przykładzie, ale byłoby to trudne aby poznać dokładne wartości wysokości, należy animować element.

JsFiddle przykład

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";
 1
Author: svnm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 19:07:48

Możesz to zrobić ze zdarzeniami przejścia, więc budujesz dwie klasy CSS dla przejścia, jedną trzymającą animację, drugą trzymającą stan display none. I przełączasz je po zakończeniu animacji? W moim przypadku mogę ponownie wyświetlić divs, jeśli nacisnę przycisk i usunę obie klasy.

Wypróbuj poniższy fragment...

$(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>
 1
Author: Miguel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 19:15:36

Jeśli używasz jQuery do ustawiania klas, zadziała to w 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>

Oczywiście możesz po prostu użyć funkcji jQuery .fadeIn() i .fadeOut(), ale zaletą ustawiania klas jest to, że chcesz przejść do wartości wyświetlania innej niż block (Jak to jest domyślne dla .fadeIn() i .fadeOut()).

Przechodzę do wyświetlania flex z ładnym efektem zanikania.

 0
Author: GSTAR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-26 10:13:40

Zamiast używać display możesz przechowywać element "poza ekranem", dopóki go nie potrzebujesz, a następnie ustawić jego pozycję tam, gdzie chcesz i przekształcić go w tym samym czasie. Wiąże się to jednak z wieloma innymi problemami projektowymi, więc przebieg może się różnić.

Prawdopodobnie nie chciałbyś używać display w każdym razie, ponieważ chciałbyś, aby zawartość była dostępna dla czytników ekranu, którzy w większości starają się przestrzegać zasad widoczności - tzn. jeśli nie powinna być widoczna dla oka, nie wyświetli się jak najbardziej zadowolona z agenta.

 0
Author: Peter Mortensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 18:04:47

Możesz po prostu użyć CSS visibility: hidden/visible zamiast display: none / 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;
}
 0
Author: foxdanni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 18:36:35

Możesz również użyć tego:

.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
Author: Peter Mortensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 18:37:31