Библиотека Focus-trap предназначена для управления фокусом внутри определённого контейнера на веб-странице. Её главная цель — ограничить перемещение фокуса пользователем только элементами внутри контейнера (например, модальными окнами, выпадающими меню, диалогами). Это предотвращает случайное взаимодействие с другими элементами страницы и повышает доступность интерфейса.
Ключевые моменты:
tabindex.Для использования Focus-trap доступна установка через npm:
npm install focus-trap
Подключение в проект:
import { createFocusTrap } from 'focus-trap';
Для создания trap используется функция createFocusTrap,
которой передаётся контейнер и объект конфигурации:
const modal = document.getElementById('modal');
const trap = createFocusTrap(modal, {
escapeDeactivates: true,
clickOutsideDeactivates: false,
allowOutsideClick: true,
initialFocus: '#first-input',
fallbackFocus: modal,
});
Пояснения ключевых опций:
Esc.Trap не активен по умолчанию. Для активации используется метод
activate(), для деактивации —
deactivate().
// Активация при открытии модального окна
trap.activate();
// Деактивация при закрытии
trap.deactivate();
Можно также передавать колбэки, чтобы реагировать на события активации и деактивации:
const trap = createFocusTrap(modal, {
onActivate: () => console.log('Trap активирован'),
onDeactivate: () => console.log('Trap деактивирован'),
});
Focus-trap автоматически определяет все фокусируемые элементы внутри контейнера:
<a href><button><input>, <textarea>,
<select>tabindexФокус при навигации с клавиатуры (Tab и
Shift+Tab) перемещается циклично по этим элементам.
Для динамических контейнеров можно использовать метод updateTabbables(), чтобы пересчитать фокусируемые элементы:
trap.updateTabbables();
Это особенно важно, если внутри модального окна добавляются новые интерактивные элементы после инициализации trap.
Trap корректно обрабатывает нажатия клавиш:
escapeDeactivates).Можно настроить кастомное поведение при этих событиях с помощью
onKeydown:
const trap = createFocusTrap(modal, {
onKeydown: (e) => {
if (e.key === 'Enter') {
console.log('Enter внутри trap');
}
},
});
При наличии нескольких интерактивных элементов на странице можно создавать несколько trap, но рекомендуется активировать только один в каждый момент времени. Конфликты решаются через:
returnFocusOnDeactivate для возврата
фокуса к исходному элементу.trap.activate();
// Работа с другим модальным окном
secondTrap.activate();
trap.deactivate(); // возвращает фокус к исходному элементу
Опция initialFocus позволяет точно задать, какой элемент
будет выбран при активации trap:
initialFocus: '#username-input'
Если элемент отсутствует или не фокусируемый, используется
fallbackFocus. Это предотвращает потерю фокуса и
гарантирует корректную работу с клавиатурой.
При динамическом добавлении контента (например, через AJAX или React-компоненты) trap может активироваться до появления всех интерактивных элементов. В этом случае рекомендуется:
updateTabbables() после добавления новых
элементов.initialFocus на существующий элемент или
использовать fallbackFocus.В одностраничных приложениях (SPA) trap помогает управлять фокусом при навигации между модальными окнами или интерактивными компонентами. Важно:
returnFocusOnDeactivate, чтобы
пользователь вернулся к предыдущему элементу после закрытия модального
окна.tabindex для логической
последовательности элементов.initialFocus, чтобы избежать
непредсказуемого поведения.clickOutsideDeactivates: false, чтобы не закрывать окно
случайным кликом.tabindex.Фокус, ограниченный библиотекой Focus-trap, обеспечивает удобство навигации с клавиатуры и повышает доступность интерфейса, особенно в сложных интерактивных приложениях. Он становится центральным инструментом для реализации корректных модальных окон, диалогов и кастомных меню, где важен контроль за фокусом и логическая последовательность навигации.