Floating UI — это библиотека для создания плавающих элементов интерфейса, таких как тултипы, всплывающие меню, поповеры и модальные окна, с гибким управлением положением и видимостью. Управление видимостью является ключевым аспектом при работе с динамическими интерфейсами, позволяя контролировать, когда элемент появляется и исчезает, а также как он взаимодействует с окружающими элементами.
В Floating UI управление видимостью делится на несколько уровней:
Состояние видимости (visible/hidden) Контроль
состояния отображения осуществляется через стандартные свойства DOM:
display, visibility, opacity.
Обычно рекомендуется использовать комбинацию opacity и
pointer-events, чтобы плавно анимировать появление
элементов без нарушения интерактивности.
const tooltip = document.querySelector('#tooltip');
tooltip.style.opacity = '1'; // показать
tooltip.style.pointerEvents = 'auto';
tooltip.style.opacity = '0'; // скрыть
tooltip.style.pointerEvents = 'none';Управление через состояние в JavaScript Часто состояние видимости хранится в переменной или реактивной структуре, например, в React или Vue. Это позволяет синхронизировать визуальное отображение с внутренней логикой приложения.
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onCl ick={() => setIsOpen(!isOpen)}>Toggle</button>
{isOpen && <FloatingElement>Содержимое</FloatingElement>}
</div>
);Использование Floating UI hooks и middleware
Floating UI предоставляет хуки, такие как useFloating, для
управления положением и видимостью. Middleware, например
hide, позволяет автоматически скрывать элемент при выходе
за пределы видимой области или пересечении с другим элементом.
import { useFloating, offset, flip, shift, hide } from '@floating-ui/react-dom';
const { x, y, reference, floating, strategy } = useFloating({
middleware: [offset(10), flip(), shift(), hide()]
});Для динамических интерфейсов критически важно корректно обрабатывать события пользователя:
reference.addEventListener('mouseenter', () => {
floating.style.opacity = '1';
});
reference.addEventListener('mouseleave', () => {
floating.style.opacity = '0';
});
Плавные анимации создают ощущение живости интерфейса. Floating UI не
навязывает конкретный способ анимации, поэтому рекомендуется
использовать CSS-переходы или анимации с
requestAnimationFrame.
.floating {
transition: opacity 0.2s ease, transform 0.2s ease;
transform: translateY(-5px);
opacity: 0;
}
.floating.show {
transform: translateY(0);
opacity: 1;
}
floating.classList.add('show'); // показать
floating.classList.remove('show'); // скрыть
Middleware hide позволяет автоматически управлять
видимостью на основе позиции относительно viewport или
reference-элемента. Можно комбинировать с кастомной логикой для сложных
интерфейсов:
import { autoUpdate } from '@floating-ui/dom';
autoUpdate(reference, floating, () => {
const rect = floating.getBoundingClientRect();
if (rect.bottom < 0 || rect.top > window.innerHeight) {
floating.style.opacity = '0';
} else {
floating.style.opacity = '1';
}
});
Появление элемента часто связано с его позиционированием. Floating UI позволяет синхронизировать эти два аспекта через хуки и middleware:
Пример комбинированного использования:
const { x, y, reference, floating } = useFloating({
placement: 'bottom',
middleware: [offset(10), flip(), shift(), hide()]
});
return (
<>
<button ref={reference}>Hover me</button>
<div ref={floating} style={{ position: 'absolute', top: y ?? 0, left: x ?? 0 }}>
Плавающий элемент
</div>
</>
);
requestAnimationFrame.Управление видимостью в Floating UI строится на сочетании:
Такой подход обеспечивает гибкое, отзывчивое и предсказуемое поведение интерфейсов, делая взаимодействие пользователя с элементами более естественным и удобным.