Библиотека 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-атрибуты. 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 предоставляет расширенные опции управления:
initialFocus — элемент, который получает фокус при
активации ловушки.returnFocusOnDeactivate — возвращает фокус на элемент,
с которого он был перед активацией.onActivate / onDeactivate — функции
обратного вызова для выполнения действий при активации или деактивации
ловушки.Пример использования initialFocus:
const focusTrap = createFocusTrap(modal, {
initialFocus: '#modal input:first-of-type',
});
Focus-trap корректно работает с контентом, который создаётся динамически через JavaScript. Для этого важно:
function openModal() {
document.body.appendChild(modal);
focusTrap.activate();
}
fallbackFocus для контейнеров без
интерактивных элементов.returnFocusOnDeactivate.Focus-trap автоматически обрабатывает навигацию по элементам с
помощью Tab и Shift+Tab. При использовании
ARIA-атрибутов:
Focus-trap позволяет удерживать фокус внутри форм, не мешая их функциональности:
Escape или клик вне контейнера безопасно деактивируют
ловушку, не нарушая обработку событий форм.aria-required, aria-invalid
можно использовать для обозначения состояния полей, оставаясь в рамках
ловушки фокуса.Focus-trap в сочетании с ARIA гарантирует, что:
aria-labelledby).aria-hidden на фоновом контенте при необходимости).Этот подход полностью соответствует стандартам WCAG 2.1, обеспечивая высокую доступность компонентов веб-приложений.