Display и visibility

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

Основная особенность заключается в том, что display в Velocity можно задавать как часть параметров анимации:

Velocity(element, {
  opacity: 1
}, {
  duration: 300,
  display: "block"
});

В этом случае после завершения анимации элемент гарантированно получит display: block. Это важно, поскольку многие эффекты появления требуют предварительного скрытия через display: none.

Автоматическое управление display через show/hide

Velocity.js включает специализированные команды, которые объединяют анимацию и управление display:

Velocity(element, "fadeIn", { duration: 300 });
Velocity(element, "fadeOut", { duration: 300 });

При использовании таких вызовов библиотека автоматически:

  • устанавливает display: none при скрытии
  • возвращает элементу исходное или заданное значение display при показе
  • синхронизирует изменение display с фазами анимации

При необходимости можно явно задать поведение:

Velocity(element, "fadeIn", {
  duration: 300,
  display: "flex"
});

Здесь итоговое состояние будет display: flex, а не block.

Значение “auto” и восстановление display

Особое значение auto используется для восстановления исходного CSS-состояния элемента:

Velocity(element, {
  opacity: 1
}, {
  display: "auto"
});

В этом случае Velocity:

  • сохраняет текущее computed display перед скрытием
  • восстанавливает его после завершения анимации
  • избегает жесткого закрепления значения block или inline

Это критично для компонентов, где display управляется CSS-классами или flex/grid-сетками.


Работа со свойством visibility

В отличие от display, свойство visibility не влияет на поток документа, но управляет визуальной доступностью элемента. Velocity.js позволяет синхронизировать visibility с анимацией, обеспечивая более гибкое управление состояниями интерфейса.

Velocity(element, {
  opacity: 1
}, {
  duration: 300,
  visibility: "visible"
});

Скрытие без влияния на layout

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

Velocity(element, {
  opacity: 0
}, {
  duration: 300,
  visibility: "hidden"
});

Такой подход часто используется в интерфейсах, где требуется плавное исчезновение без «схлопывания» макета.

Различие между display и visibility в Velocity

Поведение можно свести к нескольким фундаментальным различиям:

  • display: none полностью удаляет элемент из потока
  • visibility: hidden сохраняет место, но скрывает содержимое
  • Velocity синхронизирует оба свойства с фазами анимации

Пример комбинированного управления:

Velocity(element, {
  opacity: 0,
  translateY: 20
}, {
  duration: 400,
  display: "none",
  visibility: "hidden"
});

Синхронизация display и opacity

Наиболее частый паттерн в Velocity.js — связывание opacity с display. Это позволяет избежать ситуации, когда элемент становится невидимым, но продолжает занимать место или участвовать в событиях.

Появление элемента

Velocity(element, {
  opacity: 1,
  translateY: 0
}, {
  duration: 300,
  display: "block",
  visibility: "visible"
});

Логика выполнения:

  1. элемент получает display, если был скрыт
  2. запускается анимация opacity и transform
  3. после завершения состояние фиксируется

Исчезновение элемента

Velocity(element, {
  opacity: 0,
  translateY: 10
}, {
  duration: 300,
  display: "none"
});

Здесь display: none применяется только после завершения анимации, что предотвращает резкое исчезновение.


Использование begin и complete для контроля видимости

Velocity.js предоставляет хуки begin и complete, позволяющие вручную управлять состоянием элемента в зависимости от фазы анимации.

Принудительное управление display на старте

Velocity(element, {
  opacity: 1
}, {
  duration: 300,
  begin: function () {
    element.style.display = "block";
  }
});

Такой подход используется, когда требуется гарантированно активировать layout до начала анимации.

Финальная фиксация состояния

Velocity(element, {
  opacity: 0
}, {
  duration: 300,
  complete: function () {
    element.style.display = "none";
  }
});

Это позволяет разделить визуальную анимацию и структурное состояние DOM.


Поведение при очередях анимации

Velocity использует систему очередей, где изменение display может влиять на последующие анимации.

Velocity(element, {
  opacity: 0
}, { duration: 200 });

Velocity(element, {
  opacity: 1
}, { duration: 200 });

Если первый вызов завершает установку display: none, второй анимации может потребоваться явное восстановление:

Velocity(element, {
  opacity: 1
}, {
  duration: 200,
  display: "block"
});

Без этого элемент останется в состоянии display: none, несмотря на изменение opacity.


Анимационные паттерны появления и скрытия

Fade с сохранением layout

Velocity(element, {
  opacity: 0
}, {
  duration: 250,
  visibility: "hidden"
});

Slide + скрытие из потока

Velocity(element, {
  height: 0,
  opacity: 0
}, {
  duration: 300,
  display: "none"
});

Комбинированный UI-паттерн

Velocity(element, {
  opacity: 1,
  height: "auto",
  translateY: 0
}, {
  duration: 350,
  display: "block",
  visibility: "visible"
});

Влияние display на трансформации и производительность

Изменение display перезапускает layout-поток браузера, что может влиять на производительность анимаций. В Velocity.js это учитывается за счёт оптимизации очередности операций:

  • сначала выполняется измерение и подготовка состояния
  • затем запускается GPU-ускоренная анимация transform/opacity
  • изменение display происходит на границах анимационного цикла

Использование translate, scale и opacity вместо layout-зависимых свойств минимизирует влияние display на плавность анимации.


Управление скрытием без разрушения состояния DOM

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

Velocity(element, {
  opacity: 0
}, {
  duration: 200,
  visibility: "hidden"
});

При повторном появлении:

Velocity(element, {
  opacity: 1
}, {
  duration: 200,
  visibility: "visible"
});

Состояние DOM при этом не пересоздаётся и не влияет на соседние элементы.


Поведение при прерывании анимаций

Если анимация прерывается через Velocity(..., "stop"), состояние display может остаться промежуточным:

Velocity(element, "stop", true);

В таких случаях требуется повторная синхронизация:

Velocity(element, {
  opacity: 1
}, {
  display: "block"
});

Без этого элемент может остаться скрытым, даже если opacity изменён.


Типовые ошибки управления видимостью

  • установка display без синхронизации opacity приводит к мгновенным скачкам
  • использование visibility: hidden без анимации opacity создаёт резкие исчезновения
  • отсутствие display: block при повторном показе блокирует анимацию появления
  • смешивание CSS-классов и Velocity без контроля приоритетов ломает состояние элемента