Работа с координатами x и y

Floating UI — это современная библиотека для позиционирования плавающих элементов в браузере, которая позволяет управлять координатами элементов с высокой точностью. Основными координатами, которые используются в библиотеке, являются x и y, определяющие положение плавающего элемента относительно его reference-элемента или viewport.


Основные концепции координат

x и y представляют собой абсолютные значения позиции плавающего элемента на странице:

  • x — горизонтальное смещение от левого края viewport или контейнера.
  • y — вертикальное смещение от верхнего края viewport или контейнера.

Эти значения рассчитываются с учётом нескольких факторов:

  1. Bounding Client Rect reference-элемента.
  2. Размеров плавающего элемента (floating element).
  3. Смещения, заданного через middleware.
  4. Ограничений viewport или контейнера (через shift или flip).

Получение и использование координат

В 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: 'bottom',
  middleware: [offset(10), flip(), shift({ padding: 5 })]
}).then(({ x, y, placement }) => {
  Object.assign(floating.style, {
    left: `${x}px`,
    top: `${y}px`
  });
});

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

  • x и y возвращаются как числа в пикселях.
  • Положение плавающего элемента напрямую зависит от placement: top, bottom, left, right.
  • Middleware могут корректировать координаты для предотвращения выхода за пределы экрана.

Middleware и их влияние на координаты

  1. offset Добавляет смещение от reference-элемента:

    offset(10) // смещает floating на 10px от reference
    • x и y увеличиваются или уменьшаются в зависимости от направления (top, bottom, left, right).
  2. flip Автоматически меняет сторону плавающего элемента, если он выходит за границы viewport:

    • Координаты x и y пересчитываются с учётом нового placement.
    • Позволяет избежать перекрытия важного контента.
  3. shift Смещает элемент внутрь viewport:

    shift({ padding: 8 })
    • Координаты x и y корректируются на минимальное значение, чтобы элемент оставался видимым.
    • Используется совместно с flip для адаптивного позиционирования.

Ручная корректировка координат

Floating UI позволяет вручную изменять координаты перед применением стилей. Для этого можно использовать middleware transform или кастомные функции:

computePosition(reference, floating).then(({ x, y }) => {
  const adjustedX = x + 15; // смещение вправо
  const adjustedY = y - 5;  // смещение вверх

  Object.assign(floating.style, {
    left: `${adjustedX}px`,
    top: `${adjustedY}px`
  });
});
  • Это особенно полезно для точного выравнивания элементов, где стандартные middleware не дают желаемого результата.
  • Можно применять динамическое смещение в зависимости от размера окна или контента.

Работа с transform вместо left/top

Для улучшения производительности часто используют CSS transform: translate(), чтобы избежать перерисовки layout при изменении координат:

Object.assign(floating.style, {
  transform: `translate(${x}px, ${y}px)`
});
  • x и y остаются теми же значениями, которые возвращает computePosition.
  • При этом элемент не влияет на поток документа.
  • Уменьшается вероятность мерцания при обновлении позиции.

Учёт scrolling и контейнеров

  • Координаты x и y всегда вычисляются относительно viewport по умолчанию.
  • Если floating элемент находится внутри scrollable контейнера, нужно использовать параметр strategy: 'absolute' или strategy: 'fixed':
computePosition(reference, floating, { strategy: 'fixed' }).then(({ x, y }) => {
  Object.assign(floating.style, {
    left: `${x}px`,
    top: `${y}px`,
    position: 'fixed'
  });
});
  • При fixed координаты игнорируют прокрутку контейнеров, оставаясь привязанными к окну.
  • При absolute координаты привязываются к ближайшему position: relative контейнеру.

Динамическое обновление координат

Floating UI предоставляет autoUpdate для отслеживания изменений размеров или прокрутки:

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

const cleanup = autoUpdate(reference, floating, () => {
  computePosition(reference, floating).then(({ x, y }) => {
    Object.assign(floating.style, { left: `${x}px`, top: `${y}px` });
  });
});
  • Координаты x и y автоматически пересчитываются при resize, scroll или DOM изменениях.
  • cleanup() можно вызвать, чтобы остановить обновления.

Итоговые рекомендации по работе с x и y

  • Использовать computePosition для получения точных координат.
  • Middleware (offset, flip, shift) корректируют x и y для адаптивного позиционирования.
  • Для плавной анимации и производительности применять transform: translate(x, y).
  • Выбирать стратегию (absolute или fixed) в зависимости от контекста.
  • Для динамических интерфейсов применять autoUpdate для автоматического пересчёта координат.