Поведение на мобильных устройствах

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

Управление видимой областью (viewport)

Мобильные устройства имеют узкий экран, поэтому крайне важно корректно рассчитывать видимую область для всплывающих элементов. В Floating UI для этого используется middleware flip и shift:

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

computePosition(referenceElement, floatingElement, {
  middleware: [flip(), shift({ padding: 8 })],
});
  • flip() – автоматически меняет позицию элемента, если выбранная сторона выходит за границы viewport.
  • shift({ padding }) – смещает элемент внутрь видимой области с учетом отступа padding.

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

Учет виртуальной клавиатуры

При появлении клавиатуры viewport на мобильных устройствах уменьшается. Floating UI позволяет адаптировать позиционирование динамически с помощью autoUpdate:

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

const cleanup = autoUpdate(referenceElement, floatingElement, () => {
  computePosition(referenceElement, floatingElement, {
    middleware: [flip(), shift({ padding: 8 })],
  }).then(({ x, y }) => {
    Object.assign(floatingElement.style, {
      left: `${x}px`,
      top: `${y}px`,
    });
  });
});

autoUpdate отслеживает изменения размеров и прокрутки viewport, автоматически вызывая перерасчет позиции всплывающего элемента. Это особенно важно при появлении клавиатуры или изменении ориентации устройства.

Сенсорное взаимодействие

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

  • strategy: 'fixed' обеспечивает стабильное позиционирование даже при прокрутке страницы.
  • strategy: 'absolute' может привести к смещению элементов при быстром скролле.

Пример использования фиксированной стратегии:

computePosition(referenceElement, floatingElement, {
  strategy: 'fixed',
  middleware: [flip(), shift({ padding: 8 })],
});

Фиксированное позиционирование минимизирует «дрожание» элемента при касаниях и прокрутке.

Размеры и адаптивность

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

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

computePosition(referenceElement, floatingElement, {
  middleware: [
    size({
      apply({ availableWidth, availableHeight, rects, elements }) {
        Object.assign(elements.floating.style, {
          maxWidth: `${availableWidth}px`,
          maxHeight: `${availableHeight}px`,
        });
      },
    }),
  ],
});
  • availableWidth и availableHeight автоматически учитывают границы viewport.
  • Ограничение размеров предотвращает перекрытие системных элементов и улучшает взаимодействие с сенсорным экраном.

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

Изменение ориентации устройства с portrait на landscape требует перерасчета позиции. Использование autoUpdate с flip и shift обеспечивает корректное отображение:

const cleanup = autoUpdate(referenceElement, floatingElement, () => {
  computePosition(referenceElement, floatingElement, {
    middleware: [flip(), shift({ padding: 8 }), size()],
  }).then(({ x, y }) => {
    Object.assign(floatingElement.style, {
      left: `${x}px`,
      top: `${y}px`,
    });
  });
});

Middleware flip автоматически выбирает наилучшее направление в зависимости от доступного пространства после смены ориентации.

Практические советы для мобильных устройств

  • Всегда использовать shift({ padding: N }), чтобы элемент не касался границ экрана.
  • Middleware flip позволяет избежать «выпадения» всплывающих элементов за экран.
  • Ограничение размеров через size повышает удобство работы с сенсорным экраном.
  • Стратегия fixed предотвращает смещение элементов при скролле и касаниях.
  • autoUpdate позволяет адаптировать позицию при изменении viewport, появлении клавиатуры и ориентации.

Правильная комбинация этих middleware обеспечивает стабильное и адаптивное позиционирование всплывающих элементов на мобильных устройствах.