Tabbable — это небольшая, но мощная библиотека на
JavaScript, предназначенная для управления навигацией с клавиатуры и
определения элементов, доступных для фокусировки через клавишу Tab. Она
используется в интерфейсах, где критична доступность (accessibility), и
позволяет разработчику программно получать список фокусируемых
элементов, исключая скрытые или недоступные.
Ключевая функция библиотеки —
tabbable(container, options), которая
возвращает массив элементов внутри указанного контейнера, доступных для
табуляции.
import { tabbable } from 'tabbable';
const focusableElements = tabbable(document.body);
console.log(focusableElements); // массив всех tabbable элементов на странице
Tabbable использует строгие правила для определения
элементов:
display не
none, visibility не hidden).tabindex="-1".<input>,
<button>, <select>,
<textarea>, <a href="">)
включаются по умолчанию.tabindex="0" также считаются
фокусируемыми.Библиотека предоставляет объект опций, который позволяет гибко контролировать поведение:
includeContainer — включает сам
контейнер в список, если он фокусируемый.getShadowRoot — функция для обработки
теневых DOM, возвращает shadow root для рекурсивного поиска.strategy — может принимать значение
"strict" или "default". В режиме
"strict" игнорируются элементы с
display: contents.Пример с использованием опций:
const tabbableElements = tabbable(document.querySelector('#menu'), {
includeContainer: true,
strategy: 'strict'
});
При сложной разметке с модальными окнами, вкладками или аккордеонами
важно управлять фокусом динамически. Tabbable упрощает
делегирование управления фокусом следующим образом:
Пример реализации цикла внутри модального окна:
const modal = document.querySelector('#modal');
const elements = tabbable(modal);
modal.addEventListener('keydown', (event) => {
if (event.key === 'Tab') {
const first = elements[0];
const last = elements[elements.length - 1];
if (event.shiftKey && document.activeElement === first) {
event.preventDefault();
last.focus();
} else if (!event.shiftKey && document.activeElement === last) {
event.preventDefault();
first.focus();
}
}
});
Tabbable часто используется в крупных фреймворках и
библиотечных решениях для создания:
Для сложных компонентов удобно использовать tabbable
совместно с событиями focusin и focusout,
чтобы динамически отслеживать активный элемент и предотвращать уход
фокуса за пределы интерактивной области.
Одним из преимуществ библиотеки является поддержка теневых
DOM-деревьев. Через функцию getShadowRoot можно
обрабатывать вложенные компоненты:
const allTabbables = tabbable(document.body, {
getShadowRoot: (el) => el.shadowRoot
});
Библиотека автоматически обходит вложенные shadow root и возвращает полный список доступных элементов для табуляции, что особенно важно для современных веб-компонентов.
Иногда необходимо исключить некоторые элементы из табуляции. Можно использовать комбинацию селекторов и фильтров:
const tabbableElements = tabbable(document.body).filter(el => !el.classList.contains('ignore'));
Это позволяет делегировать управление фокусом строго нужным элементам, игнорируя скрытые или декоративные кнопки.
Tabbable оптимизирована для больших DOM-деревьев:
getShadowRoot.tabbable при работе с модальными
окнами или диалогами, чтобы исключить уход фокуса за пределы
компонента.focus() для программного управления
порядком табуляции.strategy: 'strict' при сложной верстке,
чтобы избежать непредсказуемых фокусируемых элементов.tabbable
при изменении DOM, так как список элементов может меняться.Эта библиотека является базовым инструментом для создания полностью доступных интерфейсов, где фокусировка и клавиатурная навигация управляются предсказуемо и надежно.