ARIA-атрибуты и роли

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

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

Инициализация и базовое использование

Для создания ловушки фокуса необходимо:

import { createFocusTrap } from 'focus-trap';

const modal = document.getElementById('modal');
const focusTrap = createFocusTrap(modal, {
  escapeDeactivates: true,
  clickOutsideDeactivates: true,
  fallbackFocus: '#modal',
});

focusTrap.activate();

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

  • escapeDeactivates: true — позволяет пользователю закрыть ловушку клавишей Esc.
  • clickOutsideDeactivates: true — отключает ловушку при клике вне контейнера.
  • fallbackFocus — элемент, который получит фокус, если внутри контейнера нет фокусируемых элементов.

Управление фокусом через ARIA-атрибуты и роли

Для обеспечения доступности интерфейса критически важно правильно использовать ARIA-атрибуты. Focus-trap работает в сочетании с ARIA, гарантируя, что фокус всегда находится в области с правильной семантикой.

Роли контейнера

  • role="dialog" — используется для модальных окон, обозначает независимый интерактивный элемент.
  • role="menu" — для выпадающих меню, фокус должен перемещаться по элементам внутри.
  • role="alertdialog" — уведомления, требующие немедленного внимания пользователя.

Пример модального окна:

<div id="modal" role="dialog" aria-modal="true" aria-labelledby="modal-title">
  <h2 id="modal-title">Форма обратной связи</h2>
  <button id="close-btn">Закрыть</button>
  <input type="text" placeholder="Имя">
  <input type="email" placeholder="Email">
  <button type="submit">Отправить</button>
</div>

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

  • aria-modal="true" указывает, что остальная часть страницы недоступна для взаимодействия.
  • aria-labelledby связывает модальное окно с заголовком для экранных читалок.
  • Все интерактивные элементы внутри контейнера становятся частью ловушки фокуса, предотвращая случайный выход фокуса наружу.

Настройка поведения focus-trap

Focus-trap предоставляет расширенные опции управления:

  • initialFocus — элемент, который получает фокус при активации ловушки.
  • returnFocusOnDeactivate — возвращает фокус на элемент, с которого он был перед активацией.
  • onActivate / onDeactivate — функции обратного вызова для выполнения действий при активации или деактивации ловушки.

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

const focusTrap = createFocusTrap(modal, {
  initialFocus: '#modal input:first-of-type',
});

Интеграция с динамическим контентом

Focus-trap корректно работает с контентом, который создаётся динамически через JavaScript. Для этого важно:

  1. Активировать ловушку после вставки элементов в DOM.
  2. Обновлять или пересоздавать фокусируемые элементы при изменении содержимого контейнера.
function openModal() {
  document.body.appendChild(modal);
  focusTrap.activate();
}

Лучшие практики ARIA и focus-trap

  • Всегда использовать ARIA-ролии и свойства, соответствующие типу интерактивного компонента.
  • Обеспечивать логическую последовательность фокуса для всех интерактивных элементов.
  • Не оставлять элементы без возможности фокусировки внутри модального окна или меню.
  • Использовать fallbackFocus для контейнеров без интерактивных элементов.
  • Возвращать фокус на инициирующий элемент после закрытия модального окна с помощью returnFocusOnDeactivate.

Совместимость с клавиатурой

Focus-trap автоматически обрабатывает навигацию по элементам с помощью Tab и Shift+Tab. При использовании ARIA-атрибутов:

  • Клавиатурная навигация становится предсказуемой.
  • Экранные читалки получают правильный контекст при переходе между элементами.
  • Пользователи не теряют контекст при закрытии модальных окон или переключении между меню.

Работа с формами и интерактивными элементами

Focus-trap позволяет удерживать фокус внутри форм, не мешая их функциональности:

  • Поля ввода, кнопки и селекты остаются интерактивными.
  • Escape или клик вне контейнера безопасно деактивируют ловушку, не нарушая обработку событий форм.
  • ARIA-атрибуты aria-required, aria-invalid можно использовать для обозначения состояния полей, оставаясь в рамках ловушки фокуса.

Закрепление контекста для вспомогательных технологий

Focus-trap в сочетании с ARIA гарантирует, что:

  • Экранные читалки начинают с правильного элемента (aria-labelledby).
  • Остальная часть страницы временно недоступна (aria-hidden на фоновом контенте при необходимости).
  • Пользователи, использующие только клавиатуру, не могут покинуть интерактивную область случайно.

Этот подход полностью соответствует стандартам WCAG 2.1, обеспечивая высокую доступность компонентов веб-приложений.