Переходы на дисплее: свойство

1118

В настоящее время я разрабатываю своеобразное меню "мега-выпадающего меню" CSS - в основном обычное раскрывающееся меню только для CSS, но оно содержит разные типы контента.

На данный момент, похоже, что CSS3 Transitions не относятся к свойству "display", т.е. Вы не можете выполнять какой-либо переход с display: none для display: block (или любая комбинация).

Может ли кто-нибудь подумать о способе меню второго уровня из приведенного выше примера, чтобы "исчезнуть", когда кто-то нависает над одним из пунктов меню верхнего уровня?

Я знаю, что вы можете использовать переходы в свойстве visibility: но я не могу придумать, как эффективно использовать это.

Я также пробовал использовать высоту, но это просто провалилось с треском.

Я также знаю, что это было тривиально для этого, используя JavaScript, но я хотел бросить вызов самому использовать только CSS, и я думаю, что я немного подошел.

Все и любые предложения приветствуются.

  • 0
    Работает ли переход CSS, если применить его к свойству opacity, а не к отображению?
  • 8
    положение: абсолютное; видимость: скрытая; такой же, как дисплей: нет;
Показать ещё 5 комментариев
Теги:
css-transitions

30 ответов

1066
Лучший ответ

Вы можете объединить два перехода или больше, а visibility - это то, что пригодится на этот раз.

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>

(Не забывайте, что префиксы поставщика для свойства transition)

Более подробная информация находится в в этой статье

  • 9
    Этот ответ кажется менее трудоемким, чем другие, и дает то, что мы ожидаем от отображения: нет / блок; Благодарю. Сэкономил мне кучу времени.
  • 19
    Да, проблема в том, что что-то позади этого будет перекрываться, даже если это не видно. Я нашел, используя высоту: 0 гораздо лучшее решение
Показать ещё 22 комментария
740

Вам нужно скрыть элемент другими способами, чтобы заставить это работать.

Я выполнил эффект, полностью позиционировав как <div>, и установив скрытый на opacity: 0.

Если вы даже переключите свойство display с none на block, ваш переход на другие элементы не произойдет.

Чтобы обойти это, всегда позволяйте элементу быть display: block, но скройте элемент, настроив любое из этих средств:

  • Установите height на 0.
  • Установите opacity в 0.
  • Поместите элемент за пределы рамки другого элемента с overflow: hidden.

Есть, скорее всего, больше решений, но вы не можете выполнить переход, если вы переключите элемент на display: none. Например, вы можете попробовать попробовать что-то вроде этого:

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

Но это будет не. По моему опыту, я обнаружил, что это ничего не делает.

Из-за этого вам всегда нужно сохранить элемент display: block, но вы можете обойти его, выполнив что-то вроде этого:

div {
    transition: opacity 1s ease-out;
    opacity: 0; 
    height: 0;
    overflow: hidden;
}
div.active {
    opacity: 1;
    height: auto;
}
  • 26
    Спасибо Джиму за подробный ответ. Вы абсолютно правы в том, что если свойство display: вообще изменится, то ВСЕ ваши переходы не будут работать. Который является позором - интересно, в чем причина этого. На боковой ноте, по той же ссылке, которую я разместил в исходном вопросе, вы можете увидеть, где я нахожусь с ним. Единственная (маленькая) проблема, с которой я столкнулся, - это Chrome [5.0.375.125], когда страница загружается, вы можете увидеть, как быстро исчезает меню, когда элементы загружаются на страницу. Firefox 4.0b2 и Safari 5.0 абсолютно в порядке ... ошибка или что-то я пропустил?
  • 0
    По этой ссылке я вообще не вижу переходов - ты что-то изменил? Странно, что ваша проблема возникнет только в Chrome. Это может быть ошибка и не вина на вашем конце.
Показать ещё 14 комментариев
234

На момент написания этой статьи все основные браузеры отключали CSS-переходы, если вы пытаетесь изменить свойство display, но CSS-анимации по-прежнему работают нормально, поэтому мы можем использовать их в качестве обходного пути.

Пример кода: - (Вы можете применить его к своему меню соответственно) Демо

Добавьте следующий CSS в вашу таблицу стилей: -

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

Затем примените анимацию fadeIn к дочернему fadeIn при наведении на родительский элемент: - (и, конечно, установите display: block)

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

Обновление 2019 - метод, который также поддерживает затухание:

(Некоторые JS требуется)

// 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
    Спасибо за это. Упомянутая выше уловка height: 0 (для переходов), похоже, не работает, потому что высота устанавливается на 0 при переходе с затуханием, но, похоже, этот уловка работает просто отлично.
  • 41
    Спасибо, очень полезно. Но как это исчезнуть?
Показать ещё 13 комментариев
60

Я подозреваю, что причина, по которой переходы отключены, если "отображение" изменено, происходит из-за того, что на самом деле отображается. Это не изменяет ничего, что могло бы быть плавно анимированным.

"display: none;" и "видимость: скрытая"; это две совершенно разные вещи. Оба имеют эффект, делающий элемент невидимым, но с "видимостью: скрытой"; его все еще отображается в макете, но просто не заметно. Скрытый элемент по-прежнему занимает пробел и по-прежнему отображается как встроенный или как блок или блок-строка или таблица, или что-либо, что элемент "display" сообщает ему, чтобы отображать как, и соответственно занимает место. Другие элементы автоматически не перемещаются, чтобы занять это пространство. Скрытый элемент просто не отображает фактические пиксели на выходе.

"display: none", с другой стороны, фактически полностью предотвращает рендеринг элемента. Он не занимает места макета. Другие элементы, которые занимали бы какое-то или все пространство, занимаемое этим элементом, теперь настраиваются, чтобы занять это пространство, как будто элемент просто не существовал вообще.

"display" - это не просто еще один визуальный атрибут. Он устанавливает весь режим рендеринга элемента, такой как его блок, встроенный, встроенный блок, таблица, таблица-строка, таблица-ячейка, список-элемент или что-то еще! У каждого из них очень разные разметки разметки, и не было бы разумного способа оживить или плавно перевести их (попробуйте представить плавный переход от "блока" к "встроенному" или наоборот, например!).

Вот почему переходы отключены, если отображение изменяется (даже если изменение относится к или ни от "none" - "none" - это просто invisiblity, его собственный режим рендеринга элементов, что означает отсутствие рендеринга вообще!),

  • 0
    Это правильно. Это не сразу очевидно, но как только вы задумаетесь об этом, вам не понадобится много времени, чтобы осознать, что переход свойства display не может работать .
  • 4
    Какими бы хорошими ни были вышеприведенные решения, было очень приятно получить разумное объяснение, почему переходы не применяются к атрибутам отображения.
Показать ещё 4 комментария
45

display не является одним из свойств, с которыми работает переход.

См. Https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties для списка свойств CSS, к которым могут применяться переходы. См. Https://drafts.csswg.org/css-values-4/#combining-values для того, как они интерполируются.

До CSS3 был указан в https://www.w3.org/TR/2017/WD-css-transitions-1-20171130/#animatable-css (просто закройте всплывающее окно предупреждения)

  • 0
    Ссылка больше не указывает прямо на раздел свойств анимации.
  • 1
    @AndrewLam Исправлено. Благодарю.
35

Я знаю, что это очень старый вопрос, но для людей, которые смотрят на этот поток, теперь вы можете добавить пользовательскую анимацию в свойство 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;
}

Демо

В этой демонстрации подменю изменяется от display:none до display:block и все еще удается исчезнуть.

  • 0
    Если myfirst быть showNav здесь? А как насчет Firefox? К сожалению, я не могу найти что-то связанное на демонстрационной странице, которую вы упоминаете.
  • 0
    Спасибо @SebastianG. Я сделал исправление и добавил дополнительную информацию выше.
Показать ещё 7 комментариев
19

Вместо обратных вызовов, которые не существуют в CSS, мы можем использовать свойство 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: 100%; opacity: 1;
    transition: height 0ms 0ms, opacity 600ms 0ms;
}

Итак, что здесь происходит?

  1. Когда добавляется visible класс, height и opacity начинают анимацию без задержки (0 мс), хотя height занимает 0 мс для завершения анимации (эквивалент display: block), а opacity 600 мс.

  2. Когда visible класс удаляется, opacity начинает анимацию (0 мс задержка, 400 мс), а высота ждет 400 мс и только затем мгновенно восстанавливает начальное значение (эквивалент display: none в обратном вызове анимации).

Обратите внимание, что этот подход лучше, чем тот, который использует visibility. В этом случае элемент по-прежнему занимает пространство на странице, и это не всегда удобно.

Дополнительные примеры см. В этой статье.

  • 4
    Удивлен, что у этого нет больше голосов - это умное решение так или иначе работает отлично.
  • 1
    Это работает только с height:100% что может разрушить макет в некоторых случаях. Отличное решение, если это не проблема. Один из немногих работающих двунаправленных.
Показать ещё 1 комментарий
19

Согласно Рабочий проект W3C 19 ноября 2013 г. display не является анимированным. К счастью, visibility является анимированным. Вы можете связать его переход с переходом непрозрачности (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 для тестирования:

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

Обратите внимание: если вы просто сделаете ссылку прозрачной, не установив visibility: hidden, она останется кликабельной.

  • 1
    я не вижу никакого перехода вообще в примере jsfiddle
  • 0
    @ Джино Я исправил это, изменив 0 на 0s . Судя по всему, в прошлом браузер, который я использовал для тестирования, поддерживал единичные ноль раз. Тем не менее, единичные времена не являются частью Рекомендации кандидата W3C от 29 сентября 2016 года .
Показать ещё 2 комментария
13

Мой аккуратный JavaScript трюк , чтобы разделить весь сценарий на две разные функции!

Чтобы подготовить вещи, объявляется одна глобальная переменная и определяется один обработчик события:

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

Затем, когда я скрываю элемент, я использую что-то вроде этого:

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

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

Для повторного появления элемента я делаю что-то вроде этого:

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

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

Это работает до сих пор!

  • 0
    Это работает из-за временной задержки, а не потому, что команды javascript находятся в отдельных функциях. Задержки во времени кажутся хорошим решением во многих случаях :)
11

Изменить: отображение в этом примере не применяется.

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

Что происходит выше, так это то, что через 99% экрана анимации устанавливается блокировка, а непрозрачность исчезает. В последний момент для свойства display установлено значение none.

И самый важный бит - сохранить последний кадр после окончания анимации с использованием режима анимации-заливки: вперед

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

Вот два примера: https://jsfiddle.net/qwnz9tqg/3/

  • 0
    с этим решением display: none не работает тогда?
  • 0
    Должен быть «animation-fill-mode: forward», а не «forward»
Показать ещё 4 комментария
9

Я столкнулся с этим сегодня, с модальным position: fixed, который я использовал повторно. Я не мог сохранить его display: none, а затем оживить его, поскольку он просто вскочил на внешний вид, а z-index (отрицательные значения и т.д.) Также сделал странные вещи.

Я также использовал height: 0 to height: 100%, но он работал только тогда, когда появился модальный. Это то же самое, что если вы использовали left: -100% или что-то еще.

Тогда мне показалось, что был простой ответ. Et voila:

Во-первых, ваш скрытый модальный. Обратите внимание, что height есть 0, и проверьте объявление height в переходах... он имеет 500ms, который длиннее моего перехода opacity. Помните, что это влияет на переход к постепенному исчезновению: возвращение модального состояния в состояние по умолчанию.

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

Во-вторых, ваш видимый модальный. Предположим, что вы устанавливаете .modal-active в body. Теперь height - 100%, и мой переход также изменился. Я хочу, чтобы height был немедленно изменен, а opacity - 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;
}

Что он, он работает как шарм.

  • 0
    Самый простой ответ с наименьшим количеством кода.
8

Учитывая некоторые из этих ответов и некоторые предложения в другом месте, следующее отлично работает для меню наведения (я использую это с помощью 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;
}

Вы также можете использовать height вместо max-height, если вы укажете оба значения, так как height:auto не разрешено с transition s. Значение зависания max-height должно быть больше, чем height меню может быть.

  • 1
    Это хороший трюк, но есть и недостаток. Время перехода зависит от высоты. Если есть несколько меню с переменной высотой, элементы с высотой ближе к максимальной высоте будут хорошо анимироваться. Однако, более короткие из них будут анимироваться слишком быстро, давая непоследовательный опыт.
6

Измените overflow:hidden на overflow:visible. Он работает лучше. Я использую вот так:

#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 лучше, потому что overflow:hidden действует точно так же, как a display:none.

  • 0
    Этот был билет для меня. Спасибо!
5

После принятого ответа Гильермо был написан CSS переход от 3 апреля 2012 года изменил поведение перехода на видимость и теперь можно решить эту проблему короче, без использования Переход задержки:

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

Время выполнения, указанное для обоих переходов, обычно должно быть идентичны (хотя немного больше времени для видимости не проблема). Для текущей версии см. Мой блог http://www.taccgl.org/blog/css-transition-visibility.html#visibility-opacity.

W.r.t. название вопроса "Переходы на дисплее: свойство" и в ответ на комментарии от Rui Marques и josh к принятому ответу: Это решение работает в случаях , где это не имеет значения, если дисплей или свойство видимости используется (как это, вероятно, имело место в этом вопросе). Он не будет полностью удалять элемент как отображение: none, просто сделайте это невидимым, но он все еще остается в потоке документа и влияет на положение следующих элементов. Переходы, которые полностью удаляют элемент, похожий на отображение: никто не может быть выполнен используя высоту (как указано в других ответах и ​​комментариях), max-height или margin-top/bottom, но также см. Как перейти на высоту: 0; высота: авто; используя CSS? и мой блог http://www.taccgl.org/blog/css_transition_display.html.

В ответ на комментарий Джорджа Милло: Необходимы оба свойства и оба перехода: свойство непрозрачности используется для создания анимации затухания и затухания и видимости свойство, чтобы элемент, все еще реагирующий на мышь Мероприятия. Переходы необходимы для непрозрачности визуального эффекта и видимость, чтобы задержать скрытие до тех пор, пока не исчезнет окончание.

4

Никакой javascript не требуется, и не требуется чрезмерно огромная максимальная высота. Вместо этого установите максимальную высоту в своих текстовых элементах и ​​используйте относительную единицу шрифта, такую ​​как rem или em. Таким образом, вы можете установить максимальную высоту, большую, чем ваш контейнер, избегая при этом задержки или "выскакивания", когда меню закрывается:

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
}

См. пример здесь: http://codepen.io/mindfullsilence/pen/DtzjE

  • 0
    Подобно этому вы можете установить высоту строки для вашего текста и преобразовать его в ноль. Если внутри есть только текст, контейнер будет скрыт.
  • 0
    Почему так мало голосов? Это действительно хороший ответ, и я могу использовать его.
Показать ещё 1 комментарий
4

Я подозреваю, что кто-то только начинает переходы CSS быстро обнаруживает, что они не работают, если вы одновременно модифицируете свойство display (block/none). Одна работа, о которой еще не упоминалось, заключается в том, что вы можете продолжать использовать display: block/none, чтобы скрыть/показать элемент, но установить его непрозрачность в 0, чтобы даже когда он отображался: block, он все еще невидим. Затем, чтобы угаснуть его, добавьте еще один класс CSS, такой как "on", который устанавливает непрозрачность в 1 и определяет переход для непрозрачности. Как вы могли себе представить, вам придется использовать JavaScript для добавления этого класса "on" к элементу, но по крайней мере вы по-прежнему используете CSS для фактического перехода.

P.S. Если вы окажетесь в ситуации, когда вам нужно сделать как отображение: блок, так и добавить класс "on", в то же время отложить последнее, используя setTimeout. В противном случае браузер просто видит, что происходит одновременно, и отключает переход.

  • 0
    Отлично, спасибо! Я написал другой ответ с примером, который на самом деле работает с display:none .
3

Наконец-то я нашел решение для меня, объединив opacity с position absolute (чтобы не занимать пространство, когда скрыто).

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

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

Я несколько раз сталкивался с этой проблемой, и теперь просто пошел с:

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

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

Добавив block--invisible все элементы не будут доступны для кликов, но все элементы за ним будут связаны с pointer-events:none них не поддерживается всеми основными браузерами (без IE <11).

  • 0
    Можете ли вы привести это в пример, пожалуйста?
  • 1
    Это хорошо работает, но следует отметить, что события указателя не работают с IE ниже 11
Показать ещё 1 комментарий
2

Я почти не отвечаю на вопрос с множеством ответов, но это решение имеет отличную совместимость, и я еще не видел его:

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

Объяснение: он использует трюк visibility: hidden (который совместим с "show-and-animate" за один шаг), но использует комбинацию position: absolute; z-index: -1; pointer-events: none;, чтобы убедиться, что скрытый контейнер не занимает пробел, а не отвечает на пользовательские взаимодействия.

  • 1
    Но смена position все равно заставит элемент дернуться, не так ли?
  • 0
    Ну, конечно: position: absolute означает, что элемент не занимает места, как описано в объяснении. Когда он переключается в position: static и появляется, он будет занимать пространство, как обычный элемент, что является точкой этого вопроса. Я предлагаю вам попробовать!
Показать ещё 1 комментарий
2

Я думаю, что SalmanPK имеет самый близкий ответ, он угасает элемент внутри или вне, со следующими анимациями CSS. Однако свойство отображения не анимируется плавно, а только непрозрачность.

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

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

Если вы хотите анимировать элемент, перемещающийся из блока отображения, чтобы отобразить его, я не вижу, что в настоящее время возможно только с помощью CSS, вам нужно получить высоту и использовать анимацию CSS для уменьшения высоты. Это возможно с помощью CSS, как показано в примере ниже, но было бы сложно узнать точные значения высоты, необходимые для анимации для элемента.

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

Вы можете сделать это с помощью событий перехода, так что вы так, вы строите 2 класса css для перехода, один из которых содержит анимацию, удерживая дисплей в состоянии none. и вы переключаете их после окончания анимации? В моем случае я могу отображать div снова, если я нажимаю btn и удаляю оба класса.

Попробуйте сделать снимок ниже...

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

  });

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

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

    });

  });

});
table th {
  background-color: grey;
}

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

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

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

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

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

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

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

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

Самое простое универсальное решение проблемы: не стесняйтесь указывать display:none в вашем CSS, однако вы должны изменить его на block (или что-то еще) с помощью JavaScript, а затем вам также придется добавить класс для вашего элемента, который фактически выполняет переход с помощью setTimeout(). Это все.

то есть:.

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

Протестировано в последних разумных браузерах. Очевидно, что он не должен работать в IE9 или ранее.

1

Вместо использования дисплея вы можете сохранить элемент "за кадром" до тех пор, пока он вам не понадобится, а затем установите его положение туда, где вы хотите, и преобразуйте его в одно и то же время. Это вызывает целый ряд других проблем дизайна, хотя, поэтому ymmv. Вероятно, вы не захотите использовать показ дисплея, так как вы хотите, чтобы контент был доступен для чтения с экрана, которые по большей части пытаются подчиняться правилам видимости - то есть, если это не должно быть видимым глазу, он не будет отображаться как контент для агента.

0

Если вы используете jQuery для установки ваших классов, это будет работать на 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>

Конечно, вы могли бы просто использовать функции jQuery .fadeIn() и .fadeOut(), но преимущество настройки классов вместо этого - в случае, если вы хотите перейти к отображаемому значению, отличному от block (как по умолчанию используется .fadeIn() и .fadeOut()).

Здесь я перехожу к дисплею flex с хорошим эффектом затухания.

0

Я начал проект скелетного кода с открытым исходным кодом под названием Toggle Display Animate

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

Этот помощник скелета позволит вам легко имитировать jQuery show/hide, но с анимацией перехода в CSS/CSS.

Он использует классные переключатели, поэтому вы можете использовать любые методы css, которые вы хотите использовать для элементов, кроме отображения: none | block | table | inline и т.д., а также другие альтернативные варианты использования, которые можно придумать.

Его основная цель дизайна - для состояний переключения элементов, она поддерживает состояние возврата, где скрытие объекта позволяет вам запускать ключевой кадр в обратном направлении или воспроизводить альтернативную анимацию для скрытия элемента.

Большая часть разметки для концепции, над которой я работаю, - это CSS, в действительности используется очень мало javascript.

Здесь есть демо: http://marcnewton.co.uk/projects/toggle-display-animate/

0

Вы можете заставить это работать естественным образом, как вы ожидали, - используя дисплей, - но вам нужно активировать браузер, чтобы заставить его работать, используя либо JS, либо как другие предложили фантастический трюк с одним тегом внутри другого. Меня не интересует внутренний тег, поскольку он еще более усложняет CSS и размеры, поэтому здесь решение JS:

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

Начиная с окна, например:

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

Спрятанный ящик. Вы можете переключить его на клик с помощью:

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 - это то, что вы бы предположили:

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

Ключ регулирует свойство отображения. Удалив скрытый класс, а затем ожидая 50 мс, затем, начиная переход через добавленный класс, мы получим его, чтобы он появился, а затем расширяем, как мы и хотели, вместо того, чтобы просто переключаться на экран без какой-либо анимации. Аналогично происходит другой путь, за исключением того, что мы ожидаем завершения анимации перед применением скрытого.

Примечание. Я злоупотребляю .animate(maxWidth) здесь, чтобы избежать условий гонки setTimeout. setTimeout быстро вводит скрытые ошибки, когда вы или кто-то другой захватывает код, не подозревая об этом. .animate() можно легко убить с помощью .stop(). Я просто использую его, чтобы установить задержку 50 мс или 2000 мс в стандартной очереди fx, где легко найти/разрешить другие кодеры, расположенные поверх этого.

0

вы также можете использовать это:

.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

Вы можете просто использовать css видимость: скрытый/видимый, а не дисплей: 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
    Это оставляет место, хотя, оставляя пустую дыру. Если вы хотите свернуть пространство, вам нужно оживить высоту или другое свойство.
-2

Он может обрабатываться с помощью функций синхронизации времени step-end и step-start

Например: https://jsfiddle.net/y72h8Lky/

$(".run").on("click", function() {
    $(".popup").addClass("show");
});
$(".popup").on("click", function() {
    $(".popup").removeClass("show");
})
.popup {
    opacity: 0;
    display: block;
    position: absolute;
    top: 100%;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1450;
    background-color: rgba(0, 175, 236, 0.6);
    transition: opacity 0.3s ease-out, top 0.3s step-end;
}
.popup.show {
    transition: opacity 0.3s ease-out, top 0.3s step-start;
    opacity: 1;
    top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="popup"></div>
<button class="run" style="font-size: 24px;">Click on me</button>
-2

Существует альтернативное решение с анимацией css для скрытого скрытого:

.dropdown{   
  position: relative;
  width: 100%;
 -webkit-animation-name: animatetop;
 -webkit-animation-duration: 0.4s;
 animation-name: animatetop;
 animation-duration: 0.4s
}
/* Add Animation */
@-webkit-keyframes animatetop {
 from {top:-300px; opacity:0} 
 to {top:0; opacity:1}
}

@keyframes animatetop {
 from {top:-300px; opacity:0}
 to {top:0; opacity:1}
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню