Изменение размеров floating элемента

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

Размеры floating элемента могут контролироваться через два основных подхода:

  1. Автоматическое вычисление размера с помощью size middleware.
  2. Явное ограничение размеров через CSS или JavaScript.

Middleware size

Middleware size отвечает за управление шириной и высотой floating элемента в зависимости от доступного пространства на экране. Основной синтаксис:

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

computePosition(reference, floating, {
  middleware: [
    size({
      apply({ availableWidth, availableHeight, rects, elements }) {
        Object.assign(elements.floating.style, {
          maxWidth: `${availableWidth}px`,
          maxHeight: `${availableHeight}px`
        });
      },
      padding: 8
    })
  ]
});

Пояснение параметров

  • availableWidth и availableHeight — доступное пространство вокруг целевого элемента, с учётом viewport и заданного padding.
  • rects — объект с размерами reference и floating.
  • elements.floating — сам DOM-элемент, которому нужно применить размеры.
  • padding — дополнительное пространство между floating элементом и границами viewport.

Использование size middleware позволяет:

  • Ограничивать ширину/высоту элемента, чтобы он не выходил за границы экрана.
  • Подгонять размеры под размер родителя или соседних элементов.

Автоматическая подстройка под содержимое

Если требуется, чтобы floating элемент динамически подстраивался под содержимое, можно комбинировать middleware size с flip и shift:

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

computePosition(reference, floating, {
  middleware: [
    flip(),
    shift({ padding: 10 }),
    size({
      apply({ availableWidth, elements }) {
        elements.floating.style.width = `${Math.min(300, availableWidth)}px`;
      }
    })
  ]
});

В этом примере ширина floating элемента не превышает 300px, но при этом учитывает доступное пространство вокруг reference.


Явные ограничения через CSS

Даже при использовании middleware size полезно устанавливать базовые ограничения через CSS:

.floating {
  min-width: 120px;
  max-width: 400px;
  overflow: auto;
}
  • min-width предотвращает слишком сжатые элементы.
  • max-width совместно с middleware size обеспечивает адаптивность.
  • overflow: auto позволяет скроллить содержимое, если оно превышает доступную высоту.

Динамическая подстройка при изменении окна

Floating элементы часто должны адаптироваться при изменении размеров окна. Для этого используют перерендеринг через ResizeObserver или событие resize:

const ro = new ResizeObserver(() => {
  computePosition(reference, floating, { middleware: [size()] });
});

ro.observe(reference);
window.addEventListener('resize', () => {
  computePosition(reference, floating, { middleware: [size()] });
});

Такой подход гарантирует, что floating элемент никогда не выйдет за пределы видимой области.


Использование функции computePosition с динамическими размерами

Функция computePosition позволяет управлять размерами на лету:

computePosition(reference, floating, {
  middleware: [
    size({
      apply({ availableWidth, availableHeight, elements }) {
        elements.floating.style.width = `${availableWidth * 0.8}px`;
        elements.floating.style.height = `${Math.min(availableHeight, 500)}px`;
      }
    })
  ]
});

Здесь floating элемент получает 80% доступной ширины, а высота ограничена 500px. Такой подход позволяет создавать адаптивные всплывающие окна.


Комбинирование с другими middleware

  • flip — автоматически меняет позицию при нехватке места.
  • shift — смещает элемент, чтобы не выходил за границы.
  • offset — добавляет отступ от reference.

Middleware size работает в связке с этими функциями для гибкой адаптации размеров и позиции.


Практические рекомендации

  1. Использовать size middleware для контроля размеров относительно viewport.
  2. Устанавливать CSS-ограничения (min-width, max-width) для предсказуемого поведения.
  3. Пересчитывать позиции при изменении размеров окна или содержимого reference.
  4. Комбинировать size с flip и shift для адаптивных интерфейсов.
  5. Для длинных списков применять overflow: auto и ограничивать максимальную высоту.

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