Padding и отступы от границ

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


Свойство padding

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

В Floating UI padding задаётся через объект:

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

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

computePosition(reference, floating, {
  middleware: [
    offset(10),
    flip(),
    shift({ padding: 8 })
  ],
});

Здесь ключевым является shift({ padding: 8 }):

  • padding может быть числом — одинаковый отступ со всех сторон.
  • padding может быть объектом, если требуется задать разные значения для каждой стороны:
shift({
  padding: { top: 10, bottom: 20, left: 15, right: 15 }
})
  • top, bottom, left, right определяют минимальное расстояние между плавающим элементом и соответствующей границей контейнера или viewport.

Различие между offset и padding

  • offset контролирует расстояние между триггером (reference) и плавающим элементом.
  • padding в shift контролирует расстояние между плавающим элементом и краями области отображения, предотвращая наложение на границы окна.

Пример:

middleware: [
  offset(12),            // элемент отходит от триггера на 12px
  shift({ padding: 16 }) // элемент не подходит ближе 16px к краям viewport
]

Если использовать только offset, элемент может выйти за границы окна при нехватке места. shift с padding решает эту проблему автоматически.


Поддержка динамических размеров viewport

shift с padding динамически учитывает размеры окна:

const floatingStyles = async () => {
  const { x, y } = await computePosition(reference, floating, {
    middleware: [shift({ padding: 12 })]
  });
  Object.assign(floating.style, {
    left: `${x}px`,
    top: `${y}px`
  });
};
  • Даже если пользователь изменяет размер окна, вызов computePosition с тем же padding обеспечит корректное позиционирование.
  • Padding предотвращает смещение элемента за границы экрана, что особенно важно для адаптивного дизайна.

Комбинирование с flip и autoPlacement

Когда элемент не помещается на одной стороне триггера, flip меняет сторону расположения. padding гарантирует, что при смене стороны элемент не будет вплотную к краю окна:

middleware: [
  offset(10),
  flip({ padding: 20 }),
  shift({ padding: 10 })
]
  • flip.padding задаёт отступ для смены стороны.
  • shift.padding задаёт отступ для удержания элемента внутри границ окна.
  • Использование обеих настроек обеспечивает стабильное позиционирование при сложных сценариях.

Расширенные сценарии: вложенные контейнеры

Если плавающий элемент находится внутри ограниченного контейнера (например, scrollable div), padding может быть адаптирован:

shift({
  padding: ({ rects }) => ({
    top: 8,
    bottom: 8,
    left: rects.reference.left > 50 ? 12 : 4,
    right: 12
  })
})
  • padding может быть функцией, возвращающей динамические значения на основе текущего положения триггера.
  • Это позволяет учитывать особенности макета и обеспечивать корректные отступы даже в сложных интерфейсах.

Важные нюансы

  1. Единицы измерения: Padding всегда задаётся в пикселях.
  2. Совместимость с другими middleware: shift с padding следует использовать после offset и перед flip, чтобы корректно учитывать начальные позиции.
  3. Множественные слои: Для сложных всплывающих меню с вложенными тултипами можно использовать разные padding для каждого уровня, обеспечивая визуальную иерархию.

Рекомендации по использованию

  • Минимальный padding: 8–12px для нормального UX.
  • Адаптивный padding: увеличивать для мобильных экранов, чтобы элементы не прилегали к краям.
  • Использование объекта: предпочтительнее, если интерфейс имеет асимметричные ограничения (например, фиксированная шапка сверху или панель снизу).

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