Координация с позиционированием

Floating UI предоставляет низкоуровневый механизм для вычисления позиции всплывающих элементов относительно их якорей. Центральная идея заключается в отделении логики вычисления позиции от визуального отображения, что позволяет создавать гибкие интерфейсы с тултипами, дропдаунами, поповерами и контекстными меню.

Библиотека работает с плавающими элементами, которые могут динамически менять свое положение в зависимости от доступного пространства, размеров окна и ограничения видимости. Основной принцип — передать библиотеке ссылку на элемент якоря и плавающий элемент, после чего она возвращает координаты для правильного позиционирования.


Параметры и конфигурация

Основные функции библиотеки, такие как computePosition, принимают несколько ключевых параметров:

import { computePosition, offset, flip, shift } from '@floating-ui/dom';

const reference = document.querySelector('#button');
const floating = document.querySelector('#tooltip');

computePosition(reference, floating, {
  placement: 'top',  // первичное направление относительно якоря
  middleware: [
    offset(8),        // отступ от якоря
    flip(),           // автоматический перенос при нехватке места
    shift({ padding: 5 })  // смещение в пределах видимой области
  ],
}).then(({ x, y }) => {
  Object.assign(floating.style, {
    left: `${x}px`,
    top: `${y}px`
  });
});
  • placement — определяет основное направление (top, bottom, left, right и их вариации с -start/-end).
  • middleware — массив функций, которые изменяют исходные координаты. Они позволяют создавать сложные поведения: смещение, перенос, отслеживание границ окна, автоматическое выравнивание.
  • offset — добавляет фиксированный или динамический отступ между якорем и плавающим элементом.
  • flip — проверяет, хватает ли места для выбранного placement, и при необходимости меняет направление.
  • shift — корректирует позицию, чтобы элемент оставался видимым в пределах окна.

Работа с несколькими посредниками (middleware)

Middleware в Floating UI можно комбинировать для сложного позиционирования. Примеры:

  1. Комбинация offset + flip + shift — обеспечивает безопасное отображение элемента даже на малых экранах.
  2. Arrow — middleware для выравнивания стрелки тултипа относительно центра якоря:
import { arrow } from '@floating-ui/dom';

const arrowElement = document.querySelector('#arrow');

computePosition(reference, floating, {
  placement: 'top',
  middleware: [offset(10), flip(), shift({ padding: 5 }), arrow({ element: arrowElement })]
});

Arrow возвращает координаты x и y, которые нужно применить к стрелке:

Object.assign(arrowElement.style, {
  left: `${arrowData.x}px`,
  top: `${arrowData.y}px`
});

Динамическое обновление позиции

Для интерфейсов с изменяющимся содержимым важно обновлять позицию в реальном времени. Floating UI предоставляет функцию autoUpdate, которая отслеживает изменения размеров и прокрутки:

import { autoUpdate } from '@floating-ui/dom';

const cleanup = autoUpdate(reference, floating, () => {
  computePosition(reference, floating, {
    placement: 'bottom',
    middleware: [offset(5), flip(), shift()]
  }).then(({ x, y }) => {
    Object.assign(floating.style, { left: `${x}px`, top: `${y}px` });
  });
});

// остановка наблюдения
// cleanup();

autoUpdate учитывает:

  • изменение размеров окна;
  • изменение размеров или положения якоря;
  • прокрутку родительских элементов.

Тонкости координат и рендеринга

Floating UI возвращает абсолютные координаты (x, y) относительно документа. Для точного отображения важно учитывать position CSS плавающего элемента:

  • position: absolute — координаты применяются относительно ближайшего родителя с position: relative.
  • position: fixed — координаты привязаны к окну просмотра.

С помощью middleware shift можно гарантировать, что элемент не выйдет за пределы окна или родителя с ограничениями видимости.


Комбинация с фреймворками

Floating UI хорошо интегрируется с React, Vue или Svelte, так как обеспечивает чистые данные о позиции, которые можно использовать в любом рендере. Пример с React:

import { useFloating, offset, flip, shift } from '@floating-ui/react';

function Tooltip({ referenceRef, children }) {
  const { x, y, reference, floating, strategy } = useFloating({
    middleware: [offset(10), flip(), shift()],
    placement: 'top'
  });

  return (
    <div ref={floating} style={{ position: strategy, top: y ?? 0, left: x ?? 0 }}>
      {children}
    </div>
  );
}

Ключевые моменты:

  • strategy возвращает absolute или fixed.
  • x и y — вычисленные координаты, которые можно применить к стилям.
  • Middleware управляют поведением элемента в реальном времени.

Особенности и рекомендации

  • Всегда использовать middleware для безопасного отображения на малых экранах.
  • Для стрелок и других визуальных элементов использовать middleware arrow.
  • Для динамических интерфейсов применять autoUpdate для корректного позиционирования при изменении DOM.
  • Разделять логику вычисления позиции и визуальное применение координат.

Floating UI строит позиционирование на математических расчетах, что обеспечивает точность и гибкость для любых сценариев — от простых тултипов до сложных кастомных дропдаунов и модальных окон.