Floating UI — это мощная библиотека для управления позиционированием всплывающих элементов, таких как тултипы, меню, модальные окна и popover. Два ключевых концепта, которые часто используются вместе для создания интерактивных интерфейсов — это backdrop и overlay. Они позволяют отделить всплывающий элемент от остального содержимого страницы и управлять пользовательским взаимодействием.
Overlay — это элемент, который визуально отделяет
всплывающее окно от остальной страницы. В Floating UI overlay
управляется через создание плавающего контейнера
(FloatingElement), который позиционируется относительно
целевого элемента (referenceElement) с помощью функции
computePosition.
Пример базового использования overlay:
import { computePosition, offset, flip, shift } from '@floating-ui/dom';
const reference = document.querySelector('#button');
const floating = document.querySelector('#menu');
computePosition(reference, floating, {
placement: 'bottom-start',
middleware: [offset(10), flip(), shift({ padding: 5 })],
}).then(({ x, y }) => {
Object.assign(floating.style, {
left: `${x}px`,
top: `${y}px`,
position: 'absolute',
});
});
Ключевые моменты:
placement определяет изначальное направление
всплывающего элемента относительно reference.offset задаёт расстояние между reference и
overlay.flip автоматически меняет направление при нехватке
пространства.shift предотвращает выход overlay за границы видимой
области.Overlay является самым базовым уровнем взаимодействия, но без backdrop пользователь может случайно кликнуть по элементам страницы, что иногда нежелательно.
Backdrop — это элемент, который располагается за overlay, закрывая остальное содержимое страницы и предотвращая клики по нему. Обычно используется в модальных окнах, диалогах и сложных popover.
Простейший способ создания backdrop:
const backdrop = document.createElement('div');
Object.assign(backdrop.style, {
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100vh',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
zIndex: 999,
});
document.body.appendChild(backdrop);
Особенности:
position: fixed гарантирует, что backdrop будет
покрывать весь экран независимо от прокрутки.zIndex должен быть меньше, чем у overlay, чтобы overlay
отображался поверх backdrop.backdrop.addEventListener('click', () => {
floating.style.display = 'none';
backdrop.remove();
});
Правильная комбинация overlay и backdrop создаёт пользовательский опыт, где:
Для модальных окон можно объединить их следующим образом:
function openModal(reference, modal) {
const backdrop = document.createElement('div');
Object.assign(backdrop.style, {
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100vh',
backgroundColor: 'rgba(0,0,0,0.5)',
zIndex: 1000,
});
document.body.appendChild(backdrop);
computePosition(reference, modal, {
placement: 'center',
middleware: [offset(0)],
}).then(({ x, y }) => {
Object.assign(modal.style, {
left: `${x}px`,
top: `${y}px`,
position: 'absolute',
zIndex: 1001,
});
});
backdrop.addEventListener('click', () => {
modal.style.display = 'none';
backdrop.remove();
});
}
Примечания по UX:
zIndex для правильного наложения слоев,
особенно если на странице есть другие fixed элементы.Floating UI предоставляет middleware, которые позволяют управлять поведением overlay при взаимодействии с backdrop:
flip() — меняет сторону, если overlay выходит за
экран.shift() — корректирует позицию при частичном выходе за
границы.offset() — регулирует отступ от reference.size() — автоматически подгоняет overlay по размеру
reference или контейнера.import { size } from '@floating-ui/dom';
computePosition(reference, floating, {
placement: 'bottom',
middleware: [offset(10), flip(), shift({ padding: 10 }), size({ apply: ({ rects, elements }) => {
Object.assign(elements.floating.style, {
width: `${rects.reference.width}px`,
});
}})],
});
Такой подход позволяет overlay оставаться динамичным и отзывчивым, а backdrop сохраняет роль визуального фокуса и блокировки кликов.
zIndex для overlay и backdrop, чтобы
избежать наложения с другими UI-элементами.Floating UI с overlay и backdrop предоставляет гибкий инструмент для создания всплывающих элементов с управляемой визуальной и интерактивной структурой, обеспечивая как удобство использования, так и эстетическую целостность интерфейса.