Роли и метки

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

Роли (roles)

Роль определяет, какую функциональность несёт элемент в контексте пользовательского интерфейса. В Floating UI роли чаще всего используются для определения типа всплывающего элемента и связи его с управляющим элементом (reference element).

Основные роли:

  • tooltip – всплывающая подсказка, связанная с определённым элементом.
  • menu – контекстное меню, которое появляется рядом с reference element.
  • dialog – модальное или немодальное окно, требующее особого поведения при фокусе.
  • listbox – выпадающий список опций, обычно с поддержкой клавиатурной навигации.

Присвоение роли осуществляется через стандартный атрибут role. Например:

const floating = document.createElement('div');
floating.setAttribute('role', 'tooltip');

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

Метки (aria-label и aria-labelledby)

Метки используются для улучшения доступности. Они позволяют скринридерам правильно озвучивать содержимое элементов. Floating UI не навязывает конкретные метки, но рекомендует использовать связку с reference element:

  • aria-label — прямое текстовое описание.
  • aria-labelledby — ссылка на элемент, содержащий текстовое описание.

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

const button = document.querySelector('#myButton');
const tooltip = document.createElement('div');

tooltip.setAttribute('role', 'tooltip');
tooltip.setAttribute('id', 'myTooltip');
tooltip.textContent = 'Описание кнопки';

button.setAttribute('aria-describedby', 'myTooltip');

Здесь aria-describedby связывает кнопку и tooltip, что обеспечивает корректное озвучивание подсказки для пользователей с ограничениями зрения.

Связь роли и поведения Floating UI

Роли напрямую влияют на выбор middleware и стратегий позиционирования:

  • tooltip: используется offset для небольшого отступа от reference element и flip для предотвращения выхода за пределы viewport.
  • menu: чаще применяется shift и flip для корректного отображения при изменении размеров окна.
  • dialog: важно учитывать autoUpdate, чтобы окно корректно следовало за reference element или центром экрана.

Динамическое управление ролями и метками

Floating UI предоставляет низкоуровневые функции, позволяющие динамически менять роли и метки в зависимости от состояния интерфейса:

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

const floating = document.getElementById('floating');
const reference = document.getElementById('button');

autoUpdate(reference, floating, () => {
  computePosition(reference, floating, {
    middleware: [offset(8), flip()]
  }).then(({ x, y }) => {
    Object.assign(floating.style, {
      left: `${x}px`,
      top: `${y}px`,
    });
  });
});

В этом примере можно одновременно обновлять позиции и корректно изменять атрибуты role и aria-* в зависимости от того, что отображается: tooltip, menu или dialog.

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

  • Всегда задавать role, соответствующую типу всплывающего элемента.
  • Использовать aria-describedby или aria-labelledby для связи с reference element.
  • Middleware, такие как flip, shift и offset, должны учитываться с точки зрения доступности — например, чтобы tooltip не перекрывал управляющий элемент.
  • Для сложных интерфейсов с несколькими floating elements рекомендуется хранить их состояние централизованно и динамически управлять ролями и метками.

Итоговые особенности

  • Роли: определяют функциональное предназначение элемента.
  • Метки: обеспечивают доступность и связь с reference element.
  • Middleware и позиционирование: напрямую зависят от типа роли и должны учитывать визуальные и доступностные аспекты.

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