Teleport и концепция порталов в Floating UI
предназначены для управления рендерингом всплывающих элементов вне их
исходного DOM-контекста. Это особенно важно при создании выпадающих
меню, тултипов, модальных окон и других интерфейсных компонентов, где
нужно избежать конфликтов с overflow, z-index
или стилями родительских элементов.
Отделение DOM-структуры от визуального представления Floating UI позволяет рендерить всплывающий элемент в другом месте DOM, сохраняя при этом связь с исходным элементом, относительно которого рассчитываются позиции.
Автоматическое позиционирование Даже при
переносе элемента в корень документа (document.body)
библиотека корректно рассчитывает смещение, чтобы всплывающий элемент
оставался привязанным к целевому объекту.
Совместимость с React и Vanilla JS В React можно
использовать портал через createPortal, тогда как в Vanilla
JS применяются нативные методы работы с DOM, например,
appendChild к document.body.
Пример использования в React:
import { useFloating } from '@floating-ui/react';
import { createPortal } from 'react-dom';
function Tooltip({ referenceElement, children }) {
const { x, y, strategy } = useFloating({
placement: 'top'
});
return createPortal(
<div
style={{
position: strategy,
top: y ?? 0,
left: x ?? 0
}}
>
{children}
</div>,
document.body
);
}
Пояснения:
useFloating отвечает за вычисление координат
элемента.strategy определяет метод позиционирования
(absolute или fixed).createPortal перемещает DOM-узел в
document.body, сохраняя при этом привязку к исходному
элементу.import { computePosition, offset, flip, shift } from '@floating-ui/dom';
const button = document.querySelector('#button');
const tooltip = document.createElement('div');
tooltip.textContent = 'Всплывающая подсказка';
document.body.appendChild(tooltip);
computePosition(button, tooltip, {
middleware: [offset(8), flip(), shift()]
}).then(({ x, y }) => {
Object.assign(tooltip.style, {
left: `${x}px`,
top: `${y}px`,
position: 'absolute'
});
});
computePosition вычисляет координаты с учётом смещения
(offset), возможного переворачивания (flip) и
корректировки позиции (shift).document.body, что исключает
ограничения родительских контейнеров с
overflow: hidden.Использование Teleport напрямую связано с функциональностью middleware:
Эти middleware корректно работают даже при переносе элемента в порталы, так как Floating UI рассчитывает позицию относительно исходного элемента, а не нового родителя в DOM.
При использовании порталов важно учитывать:
focusTrap и
другими библиотеками управления фокусом.overflow: hidden или z-index, ограничивающий
видимость.<div id="portals-root"></div>.offset), затем переворот
(flip) и коррекция (shift).Teleport идеально сочетается с:
Этот подход позволяет создавать сложные интерфейсы с точным позиционированием, независимые от ограничений DOM-контейнера, сохраняя при этом интерактивность, доступность и плавность анимаций.