Popper.js — это библиотека для управления позиционированием всплывающих элементов относительно других элементов на странице. Основная цель библиотеки — гарантировать корректное размещение попперов (tooltip, dropdown, меню и других overlay-компонентов) в любых условиях: при изменении размеров окна, прокрутке документа или динамическом изменении контента.
Архитектура Popper.js строится вокруг трёх ключевых компонентов: Popper, Reference и Modifiers.
Popper.js использует контекстную модель позиционирования, основанную на вычислении прямоугольных областей (bounding boxes) элементов Reference и Popper. Основные этапы вычислений:
Сбор информации о Reference и Popper: Popper.js
получает размеры и координаты элементов через
getBoundingClientRect() и учитывает свойства CSS, такие как
transform и margin.
Вычисление начальной позиции: На основе
предпочтительной стороны (placement) и размеров элементов
рассчитывается первичная позиция Popper.
Применение модификаторов: Каждый модификатор получает объект с текущей позицией и размерами и возвращает изменённое состояние. Популярные модификаторы:
offset — задаёт смещение Popper относительно
Reference.flip — автоматически меняет сторону позиционирования,
если Popper не помещается в область видимости.preventOverflow — предотвращает выход Popper за границы
контейнера или окна.arrow — позиционирует стрелку Popper в точке привязки к
Reference.Обновление DOM: После вычислений Popper.js применяет вычисленные стили к элементу Popper и, при необходимости, к стрелке или другим дочерним элементам.
Модификаторы представляют собой цепочку функций,
выполняемых в строгом порядке. Каждый модификатор получает объект
state, содержащий следующие ключевые свойства:
state.elements — элементы Popper, Reference и
стрелки.state.styles — текущие стили, применяемые к Popper и
стрелке.state.placement — текущее положение Popper (top,
bottom, left, right, с вариантами start/end).state.rects — размеры и координаты Popper и
Reference.state.modifiersData — промежуточные данные,
используемые другими модификаторами.Модификаторы могут быть основными и
дополнительными. Основные модификаторы (например,
flip или preventOverflow) отвечают за
корректность позиционирования, дополнительные — за стилизацию или
кастомные вычисления.
Popper.js управляет состоянием Popper через жизненный цикл, включающий:
Popper.js активно отслеживает изменения через события окна и MutationObserver, что позволяет динамически адаптировать Popper к:
С помощью встроенной функции update() можно вручную
инициировать перерасчёт позиции, что полезно при динамическом контенте
или анимациях.
Popper.js минимизирует количество перерисовок за счёт:
requestAnimationFrame для синхронизации
обновлений с перерисовкой браузера.Кроме того, архитектура библиотеки позволяет подключать только необходимые модификаторы, снижая нагрузку на страницу и улучшая отзывчивость интерфейса.
Система модификаторов делает Popper.js гибким и расширяемым. Создание собственного модификатора требует определения:
name),phase),fn, которая получает state и
возвращает модифицированные данные.Это позволяет интегрировать Popper.js в сложные интерфейсы, добавлять кастомную логику позиционирования и обеспечивать совместимость с современными фреймворками.
Popper.js сохраняет чёткую и модульную архитектуру, позволяя создавать надёжные и адаптивные пользовательские интерфейсы с динамическим позиционированием.