css анимация display none

Возможно вам известно, что с помощью свойств transition и animation в CSS3 можно создавать анимацию для определенных CSS-свойств . Но есть свойства, не поддающиеся анимации. Одним из них является display .

Было бы очень полезно анимировать это свойство, но это невозможно, как мне казалось до недавнего времени (ну например, как анимировать нечисловое свойство display: table ?). Но есть обходной путь, который я покажу в данной статье.

Зачем может понадобиться анимировать свойство «display»?

Нужда в анимации свойства display может исходить от необходимости решить следующие проблемы:

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

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

Давайте пошагово решим поставленную задачу.

Использование Opacity и Display

Первым делом, мы попробуем использовать оба свойства — и opacity и display . HTML-код будет таким:

CSS-код может выглядеть так:

В классе « hidden » у нас имеются значения display: none и opacity: 0 . Если мы будем подставлять данный класс с помощью jQuery, то можно использовать такой код:

Однако если мы сделаем так, то не увидим эффекта перехода, который определен в стилевом блоке .box . Получится вот что (пример в Firefox немного отличается от Chrome/IE10):

Нажмите несколько раз на кнопку « Переключение видимости » и увидите, что прямоугольник исчезает и появляется мгновенно, без перехода.

Чтобы это исправить, мы можем попробовать отделить свойство display от opacity в CSS-файле:

Теперь мы можем переключать оба класса по очереди:

Однако данный вариант не поможет нам выполнить поставленной задачи:

Нам нужно, чтобы элемент сначала плавно исчезал со страницы визуально, а затем полностью удалялся.

Даже если мы скомбинируем opacity: 0 с visibility: hidden , то несмотря на присутствие анимации, элемент по-прежнему будет занимать место на странице после исчезновения, что опять же нас не устраивает.

Почему не работает?

Перед применением моего метода, я хочу пояснить, почему мы не можем решить задачу простой поочередной заменой классов.

Во-первых, если вы будете добавлять классы так, как показано в примере выше, даже при нормально работающем переходе, необходимо будет разделить секцию для удаления и замены классов (то есть, если прямоугольник начинает скрываться, то сначала нужно установить свойство display: block , а затем изменить прозрачность).

Но этот прием не работает. JavaScript выполняет строку за строкой и не ждет выполнения операций, которые запускает каждая из них. Другими словами, если вы запускаете анимацию или другое асинхронное событие в строке 1, строка 2 будет выполнена, даже если анимация еще не закончилась.

После запуска анимации свойством opacity , а ее выполнение требует определенного времени, вы не увидите процесса, потому что строка display: none выполняется тут же.

Давайте подытожим возникшие перед нами проблемы:

  • Когда элемент видим, сначала запускаем анимацию прозрачности, а затем, после её окончания, применяем строку display: none ;
  • Когда элемент невидим, сначала устанавливаем свойство display: block , а затем пока он еще невидим, но уже присутствует на странице, запускаем анимацию.

Возможное решение

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

CSS-код не менется (два класса hidden по-прежнему разделены), а вот код jQuery будет таким:

А вот пример в действии:

Вот что этот код делает, когда прямоугольник видим:

  • Добавляет класс visuallyhidden , который запускает анимацию до полного исчезновения элемента;
  • После добавления класса, добавляется обработчик с помощью jQuery -метода .one() , который ожидает возникновения события transitionend ;
  • Событие transitionend наступает, когда анимация свойства opacity закончилась, и было установлено свойство display: block .

Так как мы не можем определить возникновение события transitionend для свойства display , то нужно использовать другой путь, когда прямоугольник невидим:

  • Сначала мы удаляем класс hidden , устанавливаем свойство display: block , пока элемент еще визуально скрыт;
  • После того, как это произошло, скрипт запускает таймер с помощью функции setTimeout() , после чего начинается анимация.

Обратите внимание, что некоторые браузеры требуют префикс для transitionend. Modernizr.prefixed() может в этом помочь.

Задержка равна 20 миллисекундам. Так как свойство display: block устанавливается мгновенно, то достаточно, чтобы элемент занял свою позицию на странице и можно запускать анимацию.

А как это сделали вы?

Как было замечено выше, возможно имеются и другие способы решения данной задачи, либо улучшения для приведенного мною решения.

Лично мне кажется, что использование функции setTimeout это оптимальный вариант. Тем более, что способ работает и, скорее всего не вызовет проблем, только если на странице не будут одновременно запускаться сотни анимаций. Но тогда это уже будет другая задача.

Данная публикация представляет собой перевод статьи « Animating from “display: block” to “display: none » , подготовленной дружной командой проекта Интернет-технологии.ру

I have a CSS Animation for a div that slides in after a set amount of time. What I would like is for a few divs to fill the space of the animated div that slides in, which it will then push those elements down the page.

When I attempt this at first div that slides in still takes up space even when it is not visible. If I change the div to display:none the div doesn’t slide in at all.

How do I have a div not take up space until it is timed to come in (using CSS for the timing.)

I am using Animate.css for the animations.

Here is what the code looks like:

As the code shows I would like the main div to be hidden and the other divs show at first. Then I have the following delay set:

It is at that point that I would like the main div to push the other divs down as it comes in.

How do I do this?

Note: I have considered using jQuery to do this, however I prefer using strictly CSS as it is smoother and the timing is a bit better controlled.

I have attempted what Duopixel suggested but either I mis-understood and am not doing this correctly or it doesn’t work. Here is the code:

Сделаю минимальный пример:

Вопрос именно про display: none , поэтому способы прозрачности и нулевой высоты взамен данного свойства не предлагать. Анимация конечно же может содержать в себе opacity , height , width , transform и прочие стили. При помощи JS, особенно с помощью jQuery, это тоже без труда реализуется, но, вопрос именно по CSS.

Если таковых нет, поделитесь, что используете и почему? Например, при сокрытии и отображении подробной информаци или обрезки текста.

Оцените статью