Backdrop и overlay

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


Overlay: основа всплывающих элементов

Overlay — это элемент, который визуально отделяет всплывающее окно от остальной страницы. В Floating UI overlay управляется через создание плавающего контейнера (FloatingElement), который позиционируется относительно целевого элемента (referenceElement) с помощью функции computePosition.

Пример базового использования overlay:

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

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

computePosition(reference, floating, {
  placement: 'bottom-start',
  middleware: [offset(10), flip(), shift({ padding: 5 })],
}).then(({ x, y }) => {
  Object.assign(floating.style, {
    left: `${x}px`,
    top: `${y}px`,
    position: 'absolute',
  });
});

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

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

Overlay является самым базовым уровнем взаимодействия, но без backdrop пользователь может случайно кликнуть по элементам страницы, что иногда нежелательно.


Backdrop: создание затемнения и блокировки взаимодействия

Backdrop — это элемент, который располагается за overlay, закрывая остальное содержимое страницы и предотвращая клики по нему. Обычно используется в модальных окнах, диалогах и сложных popover.

Простейший способ создания backdrop:

const backdrop = document.createElement('div');
Object.assign(backdrop.style, {
  position: 'fixed',
  top: 0,
  left: 0,
  width: '100vw',
  height: '100vh',
  backgroundColor: 'rgba(0, 0, 0, 0.5)',
  zIndex: 999, 
});

document.body.appendChild(backdrop);

Особенности:

  • position: fixed гарантирует, что backdrop будет покрывать весь экран независимо от прокрутки.
  • zIndex должен быть меньше, чем у overlay, чтобы overlay отображался поверх backdrop.
  • Можно добавить обработчик клика на backdrop для закрытия overlay.
backdrop.addEventListener('click', () => {
  floating.style.display = 'none';
  backdrop.remove();
});

Взаимодействие overlay и backdrop

Правильная комбинация overlay и backdrop создаёт пользовательский опыт, где:

  1. Overlay — это активный всплывающий элемент, который получает фокус и отображает контент.
  2. Backdrop — затемняет остальной интерфейс, блокирует клики и помогает сфокусировать внимание на overlay.

Для модальных окон можно объединить их следующим образом:

function openModal(reference, modal) {
  const backdrop = document.createElement('div');
  Object.assign(backdrop.style, {
    position: 'fixed',
    top: 0,
    left: 0,
    width: '100vw',
    height: '100vh',
    backgroundColor: 'rgba(0,0,0,0.5)',
    zIndex: 1000,
  });
  document.body.appendChild(backdrop);

  computePosition(reference, modal, {
    placement: 'center',
    middleware: [offset(0)],
  }).then(({ x, y }) => {
    Object.assign(modal.style, {
      left: `${x}px`,
      top: `${y}px`,
      position: 'absolute',
      zIndex: 1001,
    });
  });

  backdrop.addEventListener('click', () => {
    modal.style.display = 'none';
    backdrop.remove();
  });
}

Примечания по UX:

  • Overlay должен быть доступным для клавиатурной навигации.
  • Backdrop часто имеет анимацию появления и исчезновения, чтобы интерфейс выглядел плавно.
  • Важно учитывать zIndex для правильного наложения слоев, особенно если на странице есть другие fixed элементы.

Middleware и управление overlay

Floating UI предоставляет middleware, которые позволяют управлять поведением overlay при взаимодействии с backdrop:

  • flip() — меняет сторону, если overlay выходит за экран.
  • shift() — корректирует позицию при частичном выходе за границы.
  • offset() — регулирует отступ от reference.
  • size() — автоматически подгоняет overlay по размеру reference или контейнера.
import { size } from '@floating-ui/dom';

computePosition(reference, floating, {
  placement: 'bottom',
  middleware: [offset(10), flip(), shift({ padding: 10 }), size({ apply: ({ rects, elements }) => {
    Object.assign(elements.floating.style, {
      width: `${rects.reference.width}px`,
    });
  }})],
});

Такой подход позволяет overlay оставаться динамичным и отзывчивым, а backdrop сохраняет роль визуального фокуса и блокировки кликов.


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

  • Всегда использовать backdrop для модальных окон, чтобы предотвратить случайные клики вне overlay.
  • Настраивать zIndex для overlay и backdrop, чтобы избежать наложения с другими UI-элементами.
  • Middleware нужно комбинировать в зависимости от сценария: flip + shift для динамического позиционирования, size для адаптивных элементов.
  • Backdrop может быть прозрачным или затемнённым, в зависимости от визуальных требований.

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