Tabbable — это небольшая, но мощная библиотека для
JavaScript, предназначенная для работы с элементами страницы, доступными
для навигации с клавиатуры. Основная задача библиотеки — идентификация
элементов, на которые можно перейти с помощью клавиши Tab,
и управление их доступностью.
Библиотека не зависит от фреймворков, полностью написана на vanilla JavaScript, что делает её удобной для интеграции в любые проекты без необходимости подключения сторонних зависимостей.
Установка через npm:
npm install tabbable
Подключение в проект:
import { tabbable } from 'tabbable';
// или через require
const { tabbable } = require('tabbable');
После подключения библиотека предоставляет функции для поиска и фильтрации элементов, доступных для табуляции.
tabbable()Функция tabbable() принимает DOM-элемент в качестве
аргумента и возвращает массив элементов, которые можно выделить с
помощью клавиши Tab.
const container = document.querySelector('#form-container');
const focusableElements = tabbable(container);
console.log(focusableElements);
Важные моменты:
display: none или
visibility: hidden, не включаются.tabindex="-1" исключаются.<button>, <input>,
<select>, <textarea>,
<a href="#"> считаются табулируемыми.Можно указать контейнер, внутри которого будет происходить поиск, что полезно для модальных окон, всплывающих меню и диалогов:
const modal = document.querySelector('.modal');
const focusables = tabbable(modal);
Библиотека автоматически исключает элементы с
disabled:
<button disabled>Нельзя табулировать</button>
Такой элемент не попадет в результирующий массив.
tabindextabindex играет ключевую роль:
tabindex="0" — элемент доступен по табуляции в обычном
порядке.tabindex="-1" — элемент исключен из последовательности
табуляции, но может быть фокусирован программно.tabindex="1" и выше — задают приоритет фокусировки.
Библиотека сортирует такие элементы по возрастанию
tabindex.const focusables = tabbable(document.body);
focusables.forEach(el => console.log(el.tabIndex));
При работе с модальными окнами важно ограничивать фокус только
элементами внутри модального окна. tabbable() позволяет
получать массив всех фокусируемых элементов внутри диалога:
const modal = document.querySelector('#myModal');
const focusableInModal = tabbable(modal);
focusableInModal[0].focus();
Так можно реализовать циклическую табуляцию внутри модального окна, предотвращая выход фокуса за его пределы.
modal.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
const focusables = tabbable(modal);
const first = focusables[0];
const last = focusables[focusables.length - 1];
if (!e.shiftKey && document.activeElement === last) {
e.preventDefault();
first.focus();
} else if (e.shiftKey && document.activeElement === first) {
e.preventDefault();
last.focus();
}
}
});
opacity: 0 или находящиеся вне видимой области, все еще
могут считаться tabbable. Для полного контроля рекомендуется
использовать CSS свойства display и
visibility.tabbable() работает быстро, но лучше ограничивать область
поиска контейнером.tabindex при динамическом изменении DOM,
чтобы не нарушить естественный порядок фокусировки.tabbable() и автоматических тестов на клавиатурную
навигацию.const modals = document.querySelectorAll('.modal');
modals.forEach(modal => {
modal.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
const focusables = tabbable(modal);
const first = focusables[0];
const last = focusables[focusables.length - 1];
if (!e.shiftKey && document.activeElement === last) {
e.preventDefault();
first.focus();
} else if (e.shiftKey && document.activeElement === first) {
e.preventDefault();
last.focus();
}
}
});
});
В этом примере обеспечивается полная доступность модальных окон при использовании клавиатуры, предотвращая потерю фокуса за пределами диалога.
Библиотека Tabbable — ключевой инструмент для соблюдения
стандартов доступности (a11y) в современных веб-приложениях, упрощающий
управление фокусом и обеспечивающий удобную навигацию для пользователей
с клавиатурой.