Popper.js — это библиотека для создания динамических всплывающих элементов, таких как тултипы, поповеры и дропдауны, с учётом позиции относительно целевого элемента. Одним из ключевых аспектов, влияющих на отображение всплывающих элементов, является управление стековыми контекстами (stacking contexts) в CSS. Неправильное понимание или использование этих контекстов часто приводит к тому, что элементы оказываются перекрытыми другими DOM-элементами.
Stacking context — это концепция CSS, определяющая порядок наложения элементов по оси Z. Каждый stacking context образует отдельный слой, внутри которого элементы располагаются относительно друг друга. Внешние элементы не влияют на внутренние уровни этого контекста. Ключевые моменты:
Новый stacking context создаётся при наличии у элемента свойств:
position со значением relative,
absolute, fixed или sticky вместе
с z-index отличным от auto.opacity меньше 1.transform, filter,
perspective, clip-path и другие
CSS-свойства.will-change, указывающее на потенциальное изменение
transform или opacity.Элементы внутри одного stacking context сортируются по
z-index, но не могут “вылезти” за пределы своего контекста
относительно других внешних контекстов.
Popper.js позиционирует всплывающие элементы с помощью абсолютного или fixed позиционирования. Однако появление нового stacking context у родителя может изменить визуальный порядок наложения:
z-index, если его родитель находится
внутри stacking context с меньшим z-index.body для обхода ограничений родительских
stacking contexts.z-index и modifiers в Popper.jsДля корректного управления наложением элементов Popper.js предоставляет инструменты:
modifiers — модификаторы Popper.js позволяют влиять на поведение позиции и отображения:
zIndex — модификатор, позволяющий задавать
z-index для popper-элемента. Пример:const popperInstance = Popper.createPopper(referenceElement, popperElement, {
modifiers: [
{
name: 'zIndex',
enabled: true,
phase: 'write',
fn({ state }) {
state.elements.popper.style.zIndex = '9999';
},
},
],
});
preventOverflow и flip — косвенно помогают
избежать конфликтов наложения, корректируя позицию поппера внутри
доступной области.appendTo или порталы — в современных версиях
Popper.js возможно выводить popper в document.body, что
минимизирует влияние родительских stacking contexts.
При возникновении ситуации, когда popper скрыт за другими элементами, необходимо:
z-index и свойств,
создающих новый stacking context (transform,
opacity, filter).body) через appendTo.z-index.getComputedStyle для проверки реального
порядка слоёв.z-index.tailwind, bootstrap) часто добавляются
transform или perspective к родителям, создавая неожиданные stacking
contexts.z-index через модификатор.z-index, особенно при fixed или
sticky позиционировании.import { createPopper } from '@popperjs/core';
const reference = document.querySelector('#button');
const popper = document.createElement('div');
popper.textContent = 'Tooltip';
document.body.appendChild(popper); // портал в body
createPopper(reference, popper, {
placement: 'top',
modifiers: [
{
name: 'zIndex',
enabled: true,
fn({ state }) {
state.elements.popper.style.zIndex = '10000';
},
},
{
name: 'preventOverflow',
options: { boundary: 'viewport' },
},
],
});
В этом примере popper создаётся на уровне body, что
полностью исключает влияние родительских stacking contexts и гарантирует
корректное наложение над всеми элементами страницы.
Stacking contexts — критический аспект, определяющий видимость и
корректное наложение всплывающих элементов в Popper.js. Понимание их
механизмов и использование порталов с модификаторами
z-index и preventOverflow позволяет создавать
стабильные и предсказуемые интерфейсы.