Przejścia we właściwości wyświetlania CSS


1445

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

W tej chwili wydaje się, że przejścia CSS 3 nie mają zastosowania do właściwości „display” , tzn. Nie można wykonać żadnego rodzaju przejścia z display: nonedo display: block(lub dowolnej kombinacji).

Czy istnieje sposób, aby menu drugiego poziomu z powyższego przykładu „zanikało”, gdy ktoś najedzie myszką na jeden z elementów menu najwyższego poziomu?

Wiem, że możesz korzystać z przejść na visibility:nieruchomości, ale nie mogę wymyślić sposobu na efektywne wykorzystanie tego.

Próbowałem też użyć wysokości, ale to niestety zawiodło.

Zdaję sobie również sprawę, że osiągnięcie tego za pomocą JavaScript jest banalne, ale chciałem rzucić sobie wyzwanie, by użyć tylko CSS, i myślę, że trochę się zbliżam.


Czy przejście CSS działa, jeśli zastosujesz je do właściwości krycia, a nie do wyświetlania?
Paul D. Waite,

13
pozycja: absolutna; widoczność: ukryta; jest taki sam jak display: none;
Jawad

8
@Jawad: Tylko jeśli dodasz coś podobnego z-index:0.
DanMan

7
@Jawad: Zaleca się, aby nigdy nie używać, visibility: hiddenchyba że chcesz , aby czytniki ekranu go czytały (podczas gdy typowe przeglądarki tego nie zrobią). Określa tylko widoczność elementu (jak powiedzenie opacity: 0), i nadal można go wybierać, klikać i czymkolwiek był; to po prostu nie jest widoczne.
Forest Katsch

1
brak wsparcia dla pointer-eventsIE 8,9,10, więc nie zawsze jest ok
Steven Pribilinskiy

Odpowiedzi:


1350

Możesz połączyć dwa przejścia lub więcej i visibilitytym razem przyda się to.

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 o prefiksach dostawcy dotyczących transitionnieruchomości).

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


10
Ta odpowiedź wydaje się mniej pracy niż inne i osiąga to, czego oczekujemy od display: none / block; Dzięki. Zaoszczędził mi mnóstwo czasu.
Brendan

21
Tak, problem polega na tym, że wszystko się nakłada, nawet jeśli nie jest widoczne. Zauważyłem, że użycie wysokości: 0 jest znacznie lepszym rozwiązaniem
Josh Bedo

739
To miłe, ale problem polega na tym, że elementy „ukryte widoczność” nadal zajmują miejsce, podczas gdy „brak wyświetlania” nie.
Rui Marques

41
Prawdopodobnie czegoś mi brakuje, ale dlaczego zmieniasz zarówno widoczność, jak i krycie? Czy ustawienie przezroczystości na 0 nie spowoduje ukrycia elementu - dlaczego też musisz ustawić widoczność na ukryty?
GMA

21
@GeorgeMillo, jeśli ustawisz tylko krycie, element faktycznie jest nadal na renderowaniu strony (nie możesz na przykład kliknąć myśl).
adriendenat

800

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

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

Jeśli nawet przełączysz displaywłaściwość z nonena block, przejście na inne elementy nie nastąpi.

Aby obejść ten problem, zawsze zezwalaj na istnienie elementu display: block, ale ukryj element, dostosowując dowolny z następujących sposobów:

  1. Ustaw heightna 0.
  2. Ustaw opacityna 0.
  3. Ustaw element na zewnątrz ramy innego elementu, który ma overflow: hidden.

Prawdopodobnie jest 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 nie zadziała. Z mojego doświadczenia wynika, że ​​nic z tego nie zrobiłem.

Z tego powodu zawsze będziesz musiał zachować element display: block- ale możesz obejść go, wykonując coś takiego:

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

29
Dzięki Jim za dokładną odpowiedź. Masz absolutną rację, że jeśli właściwość display: zmieni się w ogóle, WSZYSTKIE przejścia nie będą działać. Co za wstyd - zastanawiam się, jakie jest tego uzasadnienie. Na marginesie, pod tym samym linkiem, który zamieściłem w pierwotnym pytaniu, możesz zobaczyć, gdzie jestem. Jedynym (małym) problemem, jaki mam, jest przeglądarka Chrome [5.0.375.125], gdy strona się ładuje, menu szybko zanika, gdy elementy są ładowane na stronie. Firefox 4.0b2 i Safari 5.0 są absolutnie w porządku ... błąd czy coś, co przeoczyłem?
RichardTape

7
Zgadzam się, że jest to słuszne i przyczyni się do tego; jeden na jednego dla przyszłych podróżników. Znalazłem działające rozwiązanie w Chrome, ale okazało się, że nie działa na iPhonie 4: visibility:hidden; opacity:0; -webkit-transition: all .2s ease-in-out;nie tylko to nie przechodzi poprawnie, ale element docelowy nigdy się nie pojawi. Kontrola jakości zawiedzie ciebie, mnie i twoją mamę.
SimplGy,

1
Możesz także przenieść właściwość widoczności. Mówiąc po prostu
Cu7l4ss,

2
Jeśli ustawisz stan ukryty na height: 0;i nie zmienisz go, przejście nie będzie działać. Próbowałem tego po prostu próbując zmienić przezroczystość. Musiałem usunąćheight: 0;
chovy

10
właśnie wygrałeś głosowanie dzięki bardzo overflow: hiddendziękuję!
thiagoh

277

W momencie pisania tego postu wszystkie główne przeglądarki wyłączają przejścia CSS, jeśli spróbujesz zmienić displaywłaściwość, ale animacje CSS nadal działają dobrze, więc możemy je wykorzystać jako obejście.

Przykładowy kod (możesz odpowiednio zastosować go 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 fadeInanimację do dziecka po najechaniu rodzicem (i oczywiście ustawionym display: block):

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

Aktualizacja 2019 - metoda obsługująca również wygaszanie:

(Wymagany jest 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>


3
Dzięki za to. height: 0Trik (na przemian) wspomniano powyżej, nie wydaje się działać, ponieważ wysokość zostanie ustawiona na 0 w sprawie przejścia na blaknięcie-out, ale ta sztuczka wydaje się działać dobrze.
Elliot Winkler

41
Dzięki, bardzo przydatna. Ale jak to wyciszyć?
Illiou

1
Pierwszy akapit tej odpowiedzi nie ma sensu. Przeglądarki nie tylko całkowicie wyłączają wszystkie przejścia w momencie korzystania z displaywłaściwości - naprawdę nie ma powodu. A nawet jeśli tak , to dlaczego animacje miałyby działać? Nie można również użyć tej displaywłaściwości w animacjach CSS.
BoltClock

7
Najlepsza odpowiedź, nie możliwa przy przejściach, ale tak z animacjami.
Mikel

6
Co powiesz na odwrotną animację, czyli kiedy element powinien powoli znikać?
Zielony

77

Podejrzewam, że powodem , dla którego przejścia są wyłączone, jeśli displayzostaną zmienione, jest to, co faktycznie robi wyświetlacz. To nie nie wszystko, co mogłaby być płynnie animowany zmieni.

display: none;i visibility: hidden;są dwiema zupełnie różnymi rzeczami.
Oba powodują, że element jest niewidoczny, ale visibility: hidden;nadal jest renderowany w układzie, ale po prostu nie jest widoczny .
Ukryty element nadal zajmuje miejsce i nadal jest renderowany w linii lub jako blok, blok w linii lub w tabeli, lub cokolwiek displayelement każe mu renderować jako, i odpowiednio zajmuje miejsce.
Inne elementy nie poruszają się automatycznie, aby zajmować to miejsce. Ukryty element po prostu nie renderuje rzeczywistych pikseli na wyjściu.

display: nonez drugiej strony faktycznie uniemożliwia całkowite renderowanie elementu .
To nie zajmuje żadnego miejsca układu.
Inne elementy, które zajmowałyby część lub całość miejsca zajmowanego przez ten element, teraz dostosowują się do zajmowania tego miejsca, tak jakby element po prostu w ogóle nie istniał .

displayto nie tylko kolejny atrybut wizualny.
Ustanawia ona cały tryb renderowania elementu, takie jak to, czy jest to block, inline, inline-block, table, table-row, table-cell, list-item, lub cokolwiek!
Każdy z nich ma bardzo różne konsekwencje układ, a nie byłoby rozsądnym sposobem do ożywionej lub płynnie przechodzić je (spróbuj sobie wyobrazić sprawne przejście od blockcelu inlinelub odwrotnie, na przykład!).

Właśnie dlatego przejścia są wyłączone, jeśli zmiany w wyświetlaniu (nawet jeśli zmiana dotyczy lub z none- nonenie jest po prostu niewidoczna, jest to własny tryb renderowania elementów, który oznacza brak renderowania!).


8
Chociaż powyższe rozwiązania mogą być dobre, bardzo satysfakcjonujące było uzyskanie rozsądnego wyjaśnienia, dlaczego przejścia nie mają zastosowania do atrybutów wyświetlania.
kqr

8
Nie zgadzam się. To może mieć pełny sens. Jeśli display: none to display: blok wystąpił natychmiast na początku przejścia, byłoby świetnie. I jeśli chodzi o powrót, jeśli przejdzie z display: block to display: none na końcu przejścia, byłoby idealnie.
Curtis Yallop

2
Jeśli nie możesz sobie wyobrazić, jak wygląda animacja od punktu do prostokąta, masz problemy. Przejście z zajmowania braku miejsca do zajmowania przestrzeni prostokątnej jest BARDZO oczywiste, na przykład robisz to za każdym razem, gdy przeciągasz prostokąt za pomocą myszy, jak w każdej aplikacji na świecie. W wyniku tego niepowodzenia jest tak wiele hacków z maksymalną wysokością i ujemnymi marginesami, że jest to absurdalne. Jedyne, co działa, to buforowanie „rzeczywistej” wysokości, a następnie animowanie od zera do buforowanej wartości za pomocą JavaScript. Smutny.
Triynko

2
Tryniko: display: none nie zmienia rozmiaru elementu na prostokąt 0 x 0 - usuwa go z DOM. Możesz animować od prostokąta do punktu, animując właściwości szerokości i wysokości do zera, a następnie inne elementy będą pływać wokół niego, jakby miał „display: none”, ale jego atrybut „display” pozostanie „blokiem”; element nadal znajduje się w DOM. Pojęcie animacji między wyświetlaniem: blok i wyświetlanie: żaden nie jest śmieszny: nie ma stanów pośrednich. Element istnieje w DOM lub nie istnieje, bez względu na to, jak mały lub niewidoczny.
Steve Thorpe,

1
Animowanie dyskretnych właściwości nie jest śmieszne. Dyskretnych właściwości, takich jak, displaynie można płynnie przenosić tak jak innych właściwości, ale to nie znaczy, że czas nie jest ważny. Bardzo ważna jest możliwość kontrolowania, kiedy nastąpi przejście od disply:blockdo display:none. Tak jak to opisał @CurtisYallop. Jeśli chcę, aby przejście od opacity:1celu opacity:0, a następnie zmiana display:blockna display:noneI powinny być w stanie to zrobić.
Jens

55

Zamiast wywołań zwrotnych, które nie istnieją w CSS, możemy użyć transition-delaywłaściwości.

#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 się tu dzieje?

  1. Gdy visiblegrupa jest dodawany zarówno heighti opacityrozpocząć niezwłocznie animacji (0 MS), chociaż heightbierze 0 ms do całkowitego animacji (równowartość display: block) i opacitytrwa 600 ms.

  2. Po visibleusunięciu klasy opacityrozpoczyna się animacja (opóźnienie 0 ms, czas trwania 400 ms), a wysokość czeka 400 ms, a dopiero potem natychmiast (0 ms) przywraca wartość początkową (odpowiednik display: nonew wywołaniu zwrotnym animacji).

Zauważ, że to podejście jest lepsze niż te, które używają visibility. W takich przypadkach element nadal zajmuje miejsce na stronie i nie zawsze jest odpowiedni.

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


8
zaskoczony, że nie ma więcej pozytywnych opinii - to sprytne rozwiązanie jakoś działa idealnie.
fanfara

3
Działa tylko z height:100%tym, że w niektórych przypadkach może zniszczyć układ. Świetne rozwiązanie, jeśli to nie problem. Jeden z niewielu działających dwukierunkowo.
Fabian von Ellerts,

To jest świetne! W moim przypadku mogłem to jeszcze bardziej uprościć, ponieważ chciałem, aby czas animacji wygaszania był taki sam jak czas wygaszania. Zamiast używać transition: height 0ms 0ms, opacity 600ms 0ms, po prostu użyłem transition-delay: 0s.
Jacob Lockard

52

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

Zobacz Właściwości animowanego CSS, aby uzyskać listę właściwości CSS, do których można zastosować przejścia. Zobacz CSS Moduł wartości i jednostek poziom 4, Łączenie wartości: interpolacja, dodawanie i akumulacja, aby dowiedzieć się, jak są interpolowane.

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

Próbowałem też użyć wysokości, ale to niestety zawiodło.

Ostatnim razem, gdy musiałem to zrobić, użyłem max-heightzamiast tego, która jest animowalną właściwością (chociaż było to trochę włamanie, zadziałało), ale uwaga, że ​​może być bardzo rozgoryczona w przypadku złożonych stron lub użytkowników z niskiej klasy telefonem komórkowym urządzenia.


Link nie wskazuje już bezpośrednio na sekcję właściwości animowanych.
Andrew Lam

1
@AndrewLam Naprawiono. Dzięki.
robocat

34

Możesz teraz dodać niestandardową animację do właściwości bloku.

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

Próbny

W tym demo podmenu zmienia się z display:nonena display:blocki nadal udaje się zanikać.


Powinien tu myfirstbyć showNav? A co z Firefoxem? Niestety nie mogę znaleźć czegoś związanego na stronie demo, o której wspominasz.
Sebastian vom Meer

Dzięki @SebastianG. Dokonałem korekty i dodałem więcej informacji powyżej.
Manish Pradhan

@Sebastian vom Meer: starsze wersje Firefoksa wymagają prefiksu dostawcy „-moz-”, patrz edytowany kod
Herr_Schwabullek

23
Chyba że coś mi brakuje, link „demo” nie pokazuje już przejścia do podmenu.
Realistyczne

1
Prawidłowe przejście dla czegoś, co nie zajmuje miejsca (jak w przypadku display: none) do czegoś, co zajmuje przestrzeń (display: block), jest rozszerzeniem wymiarów, a nie przenikaniem. Gdyby to była kwestia widoczności ukrytej (która zajmuje miejsce, ale nie jest widoczna) dla widocznej, wówczas rozmiar pozostaje taki sam i odpowiednie jest wprowadzanie. Żadna z tych odpowiedzi nie rozwiązuje problemu.
Triynko

21

Według W3C Working Draft 19 listopada 2013 r. display Nie jest własnością animowaną . Na szczęście visibilityjest animowany. Możesz połączyć jego przejście z przejściem krycia ( 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 = '';
    };

Pamiętaj, że jeśli ustawisz przezroczysty link, bez ustawiania visibility: hidden, pozostanie klikalny.


1
nie widzę żadnego przejścia w przykładzie jsfiddle
Gino

@Gino Naprawiłem to, zmieniając 0na 0s. Najwyraźniej w przeszłości przeglądarka, której używałem do testowania, obsługiwała zero jednostek bez jednostki. Czasy bez jednostek niejednak objęte Rekomendacją W3C dla kandydatów z 29 września 2016 r .
feklee

To powinno być bardziej oceniane. Uważam, że jest to jedno z najlepszych rozwiązań.
Arthur Tarasov

Zastosowanie opóźnienia jest najlepszą logiką, aby zrozumieć, jak to działa. Animuj i chowaj się. Odkryj i animuj. Idealne rozwiązanie dla mnie
Bruno Pitteli Gonçalves

14

Edycja: wyświetl żadna nie jest stosowana w tym przykładzie.

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

To, co dzieje się powyżej, polega na tym, że przez 99% wyświetlania animacji blokuje się, a nieprzezroczystość zanika. W ostatniej chwili właściwość display jest ustawiona na none.

Najważniejsze jest zachowanie ostatniej klatki po zakończeniu animacji za pomocą trybu animacji-wypełnienia: do przodu

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

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


z tym rozwiązaniem więc display: nonenie działa?
Bart Calixto

Powinien być „tryb animacji-wypełnienia: do przodu”, a nie „do przodu”
Alex

Edycja musi składać się z sześciu znaków i mogę tylko sugerować edycję, stąd komentarz
Alex

1
@Alex Ok. Literówka naprawiona. Co ciekawe, moja odpowiedź nie działa nawet zgodnie z oczekiwaniami, ale logiczne jest sądzić, że tak, więc zachowam ją, dopóki przeglądarki nie będą obsługiwać.
Paweł

3
Jak widać w tym skrzypce z ustawionymi kursorami display: none, tak naprawdę nigdy nie jest zaimplementowany. jsfiddle.net/3e6sduqh
robstarbuck

13

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

Aby przygotować, zadeklarowano jedną zmienną globalną i zdefiniowano jedną procedurę obsługi zdarzeń:

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

Aby ponownie wyświetlić element, robię coś takiego:

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

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

Jak dotąd działa!


Działa to z powodu opóźnienia czasowego, a nie dlatego, że polecenia javascript są w osobnych funkcjach. Opóźnienia czasowe wydają się dobrym rozwiązaniem w wielu przypadkach :)

10

Natknąłem się na to dzisiaj z position: fixedmodalem, którego użyłem ponownie. Nie mogłem go zatrzymać, display: nonea następnie ożywić, ponieważ po prostu wyskoczył i z-index(wartości ujemne itp.) Również zrobił dziwne rzeczy.

Używałem też height: 0do height: 100%, ale działało to tylko wtedy, gdy pojawił się modal. To jest tak samo, jakbyś używał left: -100%lub coś.

Wtedy uderzyło mnie, że istnieje prosta odpowiedź. Zrobione:

Po pierwsze, twój ukryty modal. Zauważ, że heightjest 0i sprawdź heightdeklarację w przejściach ... ma ona 500ms, która jest dłuższa niż moje opacityprzejście . Pamiętaj, że wpływa to na wychodzące przejście wyciszania: 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-activena body. Teraz heightjest 100%i moje przejście również się zmieniło. Chcę, żeby to heightsię natychmiast zmieniło i opacityzabrało 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 wszystko, działa jak urok.


Poparcie dla twojego stylu wyrównywania właściwości z prefiksem dostawcy 👍
George Green

9

Biorąc pod uwagę kilka z tych odpowiedzi i sugestii w innym miejscu, poniższe świetnie sprawdzają się w menu najechania kursorem (szczególnie używam tego z 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;
}

Możesz również użyć heightzamiast, max-heightjeśli określisz obie wartości, ponieważ height:autonie jest to dozwolone z transitions. Wartość wskaźnika max-heightmusi być większa niż heightw menu.


3
To niezła sztuczka, ale jest wada. Czas przejścia zależy od wysokości. Jeśli istnieje wiele menu o zmiennej wysokości, elementy o wysokości bliższej maksymalnej wysokości będą ładnie animowane. Jednak te krótsze animowałyby się zbyt szybko, dając niespójne wrażenia.
użytkownik

8

Znalazłem lepszy sposób na rozwiązanie tego problemu, możesz użyć animacji CSS i zrobić swój niesamowity efekt podczas 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)
     }
}

Dzięki za tę przydatną wskazówkę. To działa idealnie.
Sedat Kumcu

6

Znalazłem ten problem wiele razy, a teraz po prostu poszedłem z:

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

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

Dodając klasę, nie block--invisiblewszystkie elementy będą klikalne, ale wszystkie elementy za nimi będą, ponieważ pointer-events:nonesą obsługiwane przez wszystkie główne przeglądarki (brak IE <11).


Czy możesz podać to jako przykład?
GarethAS

1
Działa to dobrze, ale należy zauważyć, że zdarzenia wskaźnikowe nie działają z IE poniżej 11
user1702965

dodano notatkę dla IE poniżej 11
DominikAngerer

Jeśli chcesz mieć element na wierzchu (na przykład menu), jest to naprawdę najczystszy sposób na zrobienie tego teraz, ponieważ w 2019 r. Wsparcie jest solidnepointer-events
Josh Davenport

5

Zmień overflow:hiddenna overflow:visible. Działa lepiej. Używam w ten sposób:

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

visiblejest lepszy, ponieważ overflow:hiddenzachowuj się dokładnie jak display:none.


Ten był dla mnie biletem. Dzięki!
Dan Loewenherz,

5

JavaScript nie jest wymagany i nie jest wymagana żadna skandalicznie duża maksymalna wysokość. Zamiast tego ustaw swoje max-heightelementy tekstowe i użyj jednostki względnej czcionki, takiej jak remlub em. W ten sposób możesz ustawić maksymalną wysokość większą niż pojemnik, unikając opóźnienia lub „wyskakiwania” 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


Podobnie do tego, możesz ustawić wysokość linii w tekście i przekształcić go na zero. Jeśli w środku jest tylko tekst, ukryje to kontener.
vicmortelmans,

Dlaczego tak mało głosów? To jest naprawdę dobra odpowiedź i może być tą, której używam.
mwilcox,

@mwilcox Ponieważ używa stałej wysokości, co jest złe podczas pracy z zawartością dynamiczną (nawet szacunkowa wysokość). Jest to przydatne tylko w przypadku treści tekstowych.
Fabian von Ellerts,

5

Po napisaniu zaakceptowanej odpowiedzi Guillermo specyfikacja przejścia CSS 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 opóźnienia przejścia:

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

Czas działania określony dla obu przejść powinien zwykle być identyczny (chociaż nieco dłuższy czas widoczności nie stanowi problemu).

Aby uzyskać uruchomioną wersję, zobacz mój wpis na blogu Widoczność przejścia CSS .

Wpisz tytuł pytania „Przejścia na wyświetlaczu: właściwość” oraz w odpowiedzi na komentarze Rui Marquesa i Josha na przyjętą odpowiedź:

To rozwiązanie działa w przypadkach, w których nie ma znaczenia, czy użyto właściwości display lub visibility (jak to prawdopodobnie miało miejsce w tym pytaniu).

Nie usunie całkowicie elementu, ponieważ display:nonepo prostu uczyni go niewidocznym, ale nadal pozostanie w obiegu dokumentu i wpłynie na pozycję następujących elementów.

Przejścia, które całkowicie usuwają podobny element, display:nonemożna wykonać przy użyciu wysokości (jak wskazują inne odpowiedzi i komentarze), maksymalnej wysokości lub marginesu góra / dół, ale także zobacz Jak mogę przejść wysokość: 0; do wysokości: auto; używasz CSS? oraz mój post na blogu Obejścia dotyczące przejść CSS we właściwościach wyświetlania i wysokości .

W odpowiedzi na komentarz GeorgeMillo: Potrzebne są zarówno właściwości, jak i oba przejścia: Właściwość krycie służy do tworzenia animacji pojawiania się i zanikania oraz właściwości widoczności, aby uniknąć reagowania elementu na zdarzenia myszy. Przejścia są potrzebne dla krycia dla efektu wizualnego i dla widoczności, aby opóźnić ukrywanie się, aż do zakończenia wygaszania.


4

W końcu znalazłem rozwiązanie dla mnie, łącząc się opacityz position absolute(aby nie zajmować miejsca, gdy jest ukryty).

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

.parent:hover .toggle {
  opacity: 1;
  position: static;
}

4

Podejrzewam, że ktokolwiek dopiero rozpoczynający przejścia CSS szybko odkrywa, że ​​nie działa, jeśli modyfikujesz właściwość display (blok / none) w tym samym czasie. Jednym z obejść, o którym jeszcze nie wspomniano, jest to, że możesz nadal używać display:block/nonedo ukrywania / pokazywania elementu, ale ustaw jego krycie na 0, aby nawet gdy jest display:blockon niewidoczny.

Następnie, aby go wprowadzić, dodaj kolejną klasę CSS, taką jak „on”, która ustawia krycie na 1 i definiuje przejście dla krycia. Jak możesz sobie wyobrazić, będziesz musiał użyć JavaScript, aby dodać klasę „on” do elementu, ale przynajmniej nadal używasz CSS do faktycznego przejścia.

PS Jeśli znajdziesz się w sytuacji, w której musisz zrobić obie rzeczy display:blocki jednocześnie dodać klasę „on”, odłóż tę ostatnią za pomocą setTimeout. W przeciwnym razie przeglądarka po prostu widzi obie rzeczy jako natychmiastowe i wyłącza przejście.


Wspaniale dzięki! Napisałem inną odpowiedź z przykładem, który faktycznie działa display:none.
mojuba

4

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;

Spraw, by zniknęło, a następnie to height 0;. Upewnij się również, że używasz forwardowania, aby pozostało w końcowym stanie.


To natychmiast zresetuje się podczas usuwania klasy, więc nie jest to dobry pomysł
Sean T

2

To rozwiązanie ma doskonałą kompatybilność i 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;
}

Objaśnienie : wykorzystuje visibility: hiddenlewę (która jest zgodna z „pokaż i animuj” w jednym kroku), ale używa kombinacji, position: absolute; z-index: -1; pointer-events: none;aby upewnić się, że ukryty pojemnik nie zajmuje miejsca i nie odpowiada na interakcje użytkownika .


1
Ale zmiana positionnadal spowoduje, że element zacznie szarpać, prawda?
Arsylum,

Cóż, oczywiście: position: absoluteoznacza, że ​​element nie zajmuje miejsca, jak opisano w wyjaśnieniu. Kiedy przełączy się na position: statici pojawi się, zajmie miejsce jak zwykły element, co jest sednem tego pytania. Proponuję spróbować!
Christophe Marois

2
Zrobiłem. Ale jeśli dobrze rozumiem, pytanie dotyczyło przejścia . Jak w „płynnych animacjach”.
Arsylum,

2

Możesz sprawić, by działało to w naturalny sposób, jak się spodziewałeś - używając wyświetlacza - ale musisz dusić przeglądarkę, aby uruchomić, używając Javascript lub jak inni sugerowali wymyślną sztuczkę z jednym tagiem wewnątrz drugiego. Nie dbam o wewnętrzny tag, ponieważ dodatkowo komplikuje CSS i wymiary, więc oto rozwiązanie JavaScript:

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

Począwszy od pola takiego jak:

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

Ukryte pudełko.

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

Użyjemy sztuczki znalezionej w pokrewnym kw / d, sprawdzając offsetHeight, aby natychmiast dusić przeglądarkę:

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, aby odsłonić pudełko i wprowadzić go:

$('#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 powoduje zanikanie pola. Więc .noTrnsn()wyłącza przejściami, a następnie usuwamy hiddenklasy, który trzepie displayz nonejego domyślnie block. Następnie ustawiamy krycie na 0, aby przygotować się do przejścia. Teraz, gdy ustawiliśmy scenę, ponownie włączamy przejścia za pomocą .resumeTrnsn(). Na koniec rozpocznij przejście, ustawiając krycie na 1.

Bez biblioteki zarówno zmiana sposobu wyświetlania, jak i zmiana krycia przyniosłaby nam niepożądane efekty. Gdybyśmy po prostu usunęli wywołania biblioteki, nie uzyskalibyśmy żadnych przejść.

Zauważ, że powyższe nie ustawia ponownie wyświetlania na none na końcu animacji zanikania. Możemy jednak stać się bardziej wyszukani. Zróbmy to z takim, który zanika i rośnie na wysokości od 0.

Fantazyjny!

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

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

Teraz zmieniamy wysokość i krycie. Należy pamiętać, że nie jesteśmy ustawiania wysokości, co oznacza, że jest to domyślne auto. Konwencjonalnie nie można tego zmienić - przejście z auto na wartość piksela (np. 0) nie spowoduje przejścia. Omówimy to przy użyciu biblioteki i jeszcze jednej metody bibliotecznej:

$.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 efektów / animacji jQuery, bez konieczności korzystania z jakichkolwiek ram animacji, które są teraz wykluczone w jQuery 3.x. Nie zamierzam wyjaśniać, jak działa jQuery, ale wystarczy powiedzieć, że .queue()i .stop()hydraulika, którą zapewnia jQuery, pomaga nam uniknąć sytuacji, w której nasze animacje będą na siebie naciskać.

Animujmy efekt przesuwania w dół.

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

Kod zaczyna się od sprawdzenia, #boxczy jest obecnie ukryty, od sprawdzenia jego klasy. Ale osiąga więcej przy użyciu wait()wywołania biblioteki, dodając hiddenklasę na końcu animacji wysuwania / zanikania, której można się spodziewać, jeśli jest ona faktycznie ukryta - coś, czego powyższy prostszy przykład nie mógł zrobić. Zdarza się to również włączać 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 także zobaczyć zmiany CSS i klas wywoływane po tym, .noTrnsn()aby ogólnie ustawić scenę dla animacji, w tym wykonywanie pomiarów, takich jak pomiar ostatecznej wysokości #boxbez pokazywania tego użytkownikowi, przed wywołaniem.resumeTrnsn() i animowanie go z tego pełnego zestawu osiągnąć swój cel wartości CSS.

Stara odpowiedź

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

Możesz przejść z kliknięciem 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);
}

Kluczem jest dławienie właściwości wyświetlania. Usuwając ukrytą klasę, a następnie czekając 50 ms, a następnie rozpoczynając przejście przez klasę dodaną, wyświetlamy ją, a następnie rozwijamy tak, jak chcieliśmy, zamiast po prostu wślizgnąć się na ekran bez animacji. Podobnie dzieje się w drugą stronę, z tą różnicą, że czekamy na zakończenie animacji, zanim zastosujemy ukryte.

Uwaga: Nadużywam .animate(maxWidth)tutaj, aby uniknąć setTimeoutwarunków wyścigu. setTimeoutszybko wprowadza ukryte błędy, gdy ty lub ktoś inny nie rozumie tego kodu. .animate()można łatwo zabić .stop(). Po prostu używam go do umieszczenia opóźnienia 50 ms lub 2000 ms w standardowej kolejce fx, gdzie łatwo jest znaleźć / rozwiązać przez inne kodery budujące na tym.


1

Miałem podobny problem, na który nie mogłem znaleźć odpowiedzi. Kilka wyszukiwań Google później doprowadziło mnie tutaj. Ponieważ 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 visibilitywłaściwość CSS ma wartość, collapsektóra jest generalnie używana dla elementów tabeli. Jeśli jednak zostanie użyty w jakimkolwiek innym elemencie, skutecznie renderuje je jako ukryte , prawie tak samo jak, display: hiddenale z dodatkową możliwością, że element nie zajmuje miejsca i nadal można animować dany element.

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

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

Najprostszym uniwersalnym rozwiązaniem tego problemu jest: możesz podać display:nonew CSS, jednak zmienisz go na block(lub cokolwiek innego) za pomocą JavaScript, a następnie będziesz musiał dodać klasę do swojego elementu, który faktycznie wykonuje przejście za pomocą setTimeout () . To wszystko.

To znaczy:

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

Zostało to przetestowane w najnowszych rozsądnych przeglądarkach. Oczywiście nie powinno to działać w przeglądarce Internet Explorer 9 lub wcześniejszej.


1

Myślę, że SalmanPK ma najbliższą odpowiedź. Powoduje to zanikanie lub zmniejszanie elementu za pomocą następujących animacji CSS. Jednak właściwość display 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 przemieszczający się z bloku wyświetlacza do wyświetlenia żadnego, nie widzę, że jest to obecnie możliwe tylko z CSS. Musisz uzyskać wysokość i użyć animacji CSS, aby zmniejszyć wysokość. Jest to możliwe dzięki CSS, jak pokazano w poniższym przykładzie, ale trudno byłoby znać dokładne wartości wysokości, które należy animować dla elementu.

Przykład jsFiddle

CSS

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

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

JavaScript

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

// Push item down
element.className = element.className + " push-down";

1

Możesz to zrobić ze zdarzeniami przejścia, dzięki czemu zbudujesz dwie klasy CSS dla przejścia, jedna z animacją drugą, bez wyświetlania stanu „brak”. I zamieniasz je po zakończeniu animacji? W moim przypadku mogę ponownie wyświetlić div po naciśnięciu przycisku i usunięciu obu klas.

Wypróbuj poniższy fragment kodu ...

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


0

Jeśli używasz jQuery do ustawiania swoich 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ć jQuery .fadeIn()i .fadeOut()funkcji, ale zaletą ustawienia klas jest zamiast tego, na wypadek, gdybyś chciał przejść do wartości wyświetlanej innej niż block(jak to domyślnie za pomocą .fadeIn()i .fadeOut()).

Przejdę teraz do wyświetlania flexz ładnym efektem zanikania.


0

Zamiast używać, displaymożesz przechowywać element „poza ekranem”, dopóki go nie potrzebujesz, a następnie ustawić jego położenie w żądanym miejscu i jednocześnie przekształcić. Wiąże się to jednak z wieloma innymi problemami projektowymi, więc przebieg może się różnić.

Prawdopodobnie i tak nie chciałbyś używać display, ponieważ chciałbyś, aby treść była dostępna dla czytników ekranu, które w większości starają się przestrzegać zasad widoczności - tzn. Jeśli nie powinny być widoczne dla oka, nie pojawi się jako treść dla agenta.


0

Możesz po prostu użyć widoczności CSS : ukryty / widoczny 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;
}

5
To jednak rezerwuje miejsce, pozostawiając pustą dziurę. Jeśli chcesz zwinąć przestrzeń, musisz animować wysokość lub inną właściwość.
Marcy Sutton,

0

Rozpocząłem projekt szkieletowy open source o nazwie Toggle Display Animate .

Ten szkieletowy pomocnik pozwoli ci łatwo naśladować pokazywanie / ukrywanie jQuery, ale dzięki animacjom przejścia CSS 3.

Używa przełączników klas, dzięki czemu można używać dowolnych metod CSS na elementach oprócz display: none | block | table | inline itp., A także innych alternatywnych zastosowań, które można wymyślić.

Jego głównym celem jest tworzenie stanów przełączania elementów i obsługuje stan przywracania, w którym ukrywanie obiektu pozwala na uruchomienie klatki kluczowej w odwrotnej kolejności lub odtworzenie alternatywnej animacji w celu ukrycia elementu.

Większość znaczników dla koncepcji, nad którą pracuję, to CSS, a JavaScript jest bardzo mało używana.

Tutaj jest demo: http://marcnewton.co.uk/projects/toggle-display-animate/

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.