Popper.js изначально разрабатывался как библиотека для управления позиционированием всплывающих элементов (popper) относительно целевых элементов (reference). Несмотря на то, что Popper.js сам по себе не предоставляет встроенных средств анимации, он обеспечивает гибкие механизмы, которые позволяют интегрировать CSS-анимации и transitions без нарушения корректного позиционирования.
Ключевая идея заключается в том, что Popper.js динамически управляет позициями и стилями элементов через JavaScript, но не вмешивается в визуальные эффекты появления, исчезновения или движения. Поэтому анимации строятся на уровне CSS, а Popper.js обеспечивает стабильность положения элементов.
Для базовой анимации всплывающих элементов чаще всего применяется
свойство transition в CSS. Рассмотрим пример плавного
появления и исчезновения:
.popper {
opacity: 0;
transform: scale(0.95);
transition: opacity 0.3s ease, transform 0.3s ease;
}
.popper[data-show] {
opacity: 1;
transform: scale(1);
}
.popper — основной элемент popper.opacity и transform управляют визуальным
эффектом появления.data-show добавляется и удаляется через
JavaScript, управляя состоянием анимации.В JavaScript необходимо синхронизировать атрибут с жизненным циклом Popper.js:
import { createPopper } from '@popperjs/core';
const button = document.querySelector('#button');
const tooltip = document.querySelector('#tooltip');
const popperInstance = createPopper(button, tooltip, {
placement: 'top',
});
function show() {
tooltip.setAttribute('data-show', '');
popperInstance.update();
}
function hide() {
tooltip.removeAttribute('data-show');
}
Важный момент: popperInstance.update() гарантирует, что
позиция будет пересчитана после изменений DOM, что предотвращает
дрожание или смещение во время анимации.
Популярные библиотеки для анимаций, такие как GSAP или Anime.js, могут использоваться совместно с Popper.js для более сложных эффектов. Ключевая стратегия: Popper.js управляет позиционированием, а внешняя библиотека — визуальными эффектами.
Пример с GSAP:
import { gsap } from 'gsap';
import { createPopper } from '@popperjs/core';
const button = document.querySelector('#button');
const tooltip = document.querySelector('#tooltip');
const popperInstance = createPopper(button, tooltip, { placement: 'bottom' });
function show() {
popperInstance.update();
gsap.to(tooltip, { opacity: 1, y: 0, duration: 0.3 });
}
function hide() {
gsap.to(tooltip, { opacity: 0, y: -10, duration: 0.3 });
}
y — вертикальное смещение элемента.popperInstance.update() вызывается перед анимацией,
чтобы позиция элемента была актуальной.Popper.js поддерживает динамическое изменение placement и автоматическое обновление позиции при изменении контекста. Для плавного визуального перехода можно использовать CSS-переходы:
.popper {
transition: transform 0.2s ease;
}
popperInstance.setOptions({
modifiers: [
{
name: 'flip',
options: {
fallbackPlacements: ['top', 'right', 'bottom', 'left'],
},
},
],
});
Когда flip изменяет позицию popper, CSS
transition создаёт эффект мягкого смещения без рывков. Этот
приём особенно эффективен для адаптивных интерфейсов и всплывающих
подсказок, меняющих ориентацию при изменении размера окна.
Для сложных сценариев анимации полезно использовать события
жизненного цикла Popper.js через модификаторы. Например,
модификатор eventListeners позволяет синхронизировать
анимацию с событиями scroll и resize:
const popperInstance = createPopper(button, tooltip, {
modifiers: [
{
name: 'eventListeners',
options: { scroll: true, resize: true },
},
],
});
scroll: true — обновление позиции при прокрутке.resize: true — обновление позиции при изменении
размеров окна.Это позволяет безопасно применять CSS-анимации, не опасаясь, что popper “вылетит” за границы видимой области.
Для создания плавного появления и исчезновения всплывающих элементов
лучше комбинировать opacity и visibility:
.popper {
opacity: 0;
visibility: hidden;
transition: opacity 0.25s ease;
}
.popper[data-show] {
opacity: 1;
visibility: visible;
}
opacity управляет визуальным эффектом.visibility исключает кликабельность элемента, пока он
скрыт.data-show обеспечивает контроль через
JavaScript без вмешательства в вычисления Popper.js.popperInstance.update() перед началом
анимации, чтобы popper был на актуальной позиции.transform предпочтительнее
top/left, так как она аппаратно ускорена и не
вызывает пересчёта layout.data-show или классами
для управления состоянием появления.placement использовать
CSS-переходы для плавного смещения.Эти подходы обеспечивают совместимость Popper.js с любыми визуальными эффектами, сохраняя точность позиционирования и плавность интерфейса.