Ориентация экрана

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

Определение ориентации

Ориентация экрана влияет на то, как элемент отображается на различных устройствах:

  • Портретная (portrait) — высота больше ширины. Часто используется на мобильных телефонах и планшетах.
  • Альбомная (landscape) — ширина больше высоты. Применяется на десктопах, ноутбуках и некоторых планшетах.

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

Middleware для адаптации к экрану

Основные middleware, влияющие на ориентацию и позиционирование:

  1. flip

    • Автоматически меняет сторону отображения всплывающего элемента, если выбранное место не помещается в видимой области.
    • Работает с placement (top, bottom, left, right) и автоматически подстраивается под текущую ориентацию.
    • Пример использования:
    import { computePosition, flip } from '@floating-ui/dom';
    
    const button = document.querySelector('#button');
    const tooltip = document.querySelector('#tooltip');
    
    computePosition(button, tooltip, {
      placement: 'bottom',
      middleware: [flip()],
    }).then(({ x, y }) => {
      Object.assign(tooltip.style, {
        left: `${x}px`,
        top: `${y}px`,
      });
    });

    В портретной ориентации элемент может автоматически переместиться вверх, если снизу нет места.

  2. shift

    • Смещает элемент внутри видимой области, предотвращая выход за границы окна.
    • Поддерживает ограничение по осям mainAxis и crossAxis.
    • Особенно полезно при портретной ориентации, когда горизонтальное пространство ограничено.
    import { shift } from '@floating-ui/dom';
    
    computePosition(button, tooltip, {
      placement: 'top',
      middleware: [shift({ padding: 8 })],
    });
  3. autoPlacement

    • Комбинирует flip и shift, автоматически выбирая оптимальное место для элемента.
    • Позволяет реагировать на изменения ориентации без ручного пересчета.
    import { autoPlacement } from '@floating-ui/dom';
    
    computePosition(button, tooltip, {
      middleware: [autoPlacement()],
    });

Отслеживание изменений ориентации

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

window.addEventListener('resize', () => {
  computePosition(button, tooltip, {
    placement: 'bottom',
    middleware: [flip(), shift({ padding: 5 })],
  }).then(({ x, y }) => {
    Object.assign(tooltip.style, {
      left: `${x}px`,
      top: `${y}px`,
    });
  });
});

Позиционирование с учётом ограничений экрана

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

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

computePosition(button, tooltip, {
  placement: 'top',
  middleware: [
    offset(10),
    flip({ boundary: document.body }),
    shift({ boundary: document.body, padding: 5 })
  ],
});
  • offset(10) — добавляет отступ между целевым элементом и всплывающим.
  • flip и shift гарантируют видимость вне зависимости от ориентации.

Практическая стратегия

  • Использовать autoPlacement для элементов с динамическим положением.
  • Применять shift для предотвращения выхода за границы экрана.
  • Обрабатывать событие resize или orientationchange, чтобы корректно пересчитывать координаты.
  • Учитывать padding и boundaries для предотвращения перекрытий с краями экрана.

Тонкая настройка для разных устройств

Для разных типов устройств и ориентаций можно использовать разные комбинации middleware:

  • Мобильные устройства (портрет): shift({ padding: 8 }), flip().
  • Планшеты (альбом): autoPlacement({ allowedPlacements: ['top', 'bottom'] }).
  • Десктоп: можно использовать фиксированные placement без shift, если место достаточно.

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