Screen reader поддержка

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

ARIA-атрибуты для интерактивных элементов

Для корректной работы экранных читалок необходимо использовать ARIA-атрибуты, которые сообщают пользователю о роли и состоянии элементов интерфейса:

  • role – определяет тип интерактивного элемента. Например, для тултипа используют role="tooltip", для модального окна – role="dialog".
  • aria-labelledby – указывает на элемент, который служит заголовком всплывающего окна или тултипа.
  • aria-describedby – связывает всплывающий элемент с описанием или дополнительной информацией.
  • aria-hidden – скрывает элементы, которые не должны быть доступны экранным читалкам, особенно при динамическом отображении и скрытии элементов.

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

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

function Tooltip({ label, children }) {
  const { x, y, reference, floating } = useFloating({
    placement: 'top',
  });

  return (
    <>
      <button ref={reference} aria-describedby="tooltip">
        {children}
      </button>
      <div
        ref={floating}
        id="tooltip"
        role="tooltip"
        style={{
          position: 'absolute',
          top: y ?? 0,
          left: x ?? 0,
        }}
      >
        {label}
      </div>
    </>
  );
}

Фокусировка и клавиатурная навигация

Экранные читалки тесно связаны с поведением клавиатурного фокуса. Floating UI позволяет интегрировать управление фокусом через вспомогательные хуки:

  • focus management – при открытии всплывающего элемента рекомендуется автоматически переводить фокус на него или на первый интерактивный элемент внутри.
  • keyboard interactions – обработка клавиш Tab, Escape и стрелок для навигации между элементами.

Пример управления фокусом для модального окна:

function Modal({ isOpen, onClose }) {
  const { x, y, reference, floating } = useFloating();

  useEffect(() => {
    if (isOpen) {
      floating.current?.focus();
    }
  }, [isOpen]);

  return isOpen ? (
    <div
      ref={floating}
      role="dialog"
      tabIndex={-1}
      aria-modal="true"
      style={{ position: 'absolute', top: y, left: x }}
    >
      <button onCl ick={onClose}>Закрыть</button>
      Контент модального окна
    </div>
  ) : null;
}

Динамическое обновление ARIA-атрибутов

Когда позиция или видимость всплывающего элемента изменяется динамически, экранная читалка должна получать обновлённую информацию:

  • Использовать aria-live для сообщений, которые меняются без перезагрузки страницы.
  • Применять MutationObserver для наблюдения за изменениями контента и автоматического уведомления читалки.
<div
  role="status"
  aria-live="polite"
>
  {dynamicMessage}
</div>

Обеспечение доступности при адаптивной позиции

Floating UI поддерживает автоматическую корректировку позиции (middleware flip, shift), но при этом необходимо следить за сохранением логики доступности:

  • Элементы, которые появляются на экране, должны быть связаны с элементами управления через aria-describedby или aria-labelledby.
  • Если элемент перемещается динамически, его видимость и фокус должны оставаться синхронизированными с DOM, чтобы экранная читалка могла корректно прочитать его содержимое.

Проверка совместимости с экранными читалками

Для оценки доступности рекомендуется использовать следующие подходы:

  1. NVDA или VoiceOver – проверка озвучивания ролей и контента.
  2. ChromeVox – тестирование поведения всплывающих элементов в браузере Chrome.
  3. axe-core – автоматизированная проверка ARIA-атрибутов и фокусируемости элементов.

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

Интеграция с библиотеками управления состоянием

Часто используется комбинация Floating UI и React-подходов к управлению состоянием:

  • useState или useReducer – для отслеживания открытия/закрытия элементов.
  • useEffect – для синхронизации фокуса и обновления ARIA-атрибутов.
  • Важно поддерживать согласованность состояния видимости и ARIA: экранная читалка должна знать о всех изменениях.
const [isOpen, setIsOpen] = useState(false);

return (
  <>
    <button onCl ick={() => setIsOpen(!isOpen)}>Открыть меню</button>
    {isOpen && <DropdownMenu />}
  </>
);

Итоги по доступности

  • Использование ARIA-атрибутов role, aria-labelledby, aria-describedby и aria-hidden.
  • Управление фокусом и клавиатурными событиями при открытии всплывающих элементов.
  • Динамическое уведомление экранных читалок с помощью aria-live и синхронизация с DOM.
  • Тестирование с реальными читалками и автоматизированными инструментами.

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