Библиотека Tabbable предназначена для определения элементов на странице, доступных для навигации с помощью клавиши Tab. Она анализирует DOM и возвращает массив элементов, которые могут быть фокусированы пользователем. Основная цель — управление доступностью интерфейса и корректная навигация по интерактивным компонентам.
Важной особенностью является фильтрация элементов, которые визуально присутствуют, но не должны участвовать в цикле табуляции. Это позволяет создавать динамические интерфейсы, где скрытые или неактивные элементы не мешают пользователю.
Функция tabbable(container) возвращает массив
активных для табуляции элементов внутри указанного
контейнера.
import tabbable from "tabbable";
const focusableElements = tabbable(document.body);
console.log(focusableElements);
Ключевые моменты:
<a> с
href, <button>,
<input>, <select>,
<textarea>, элементы с
tabindex="0".disabled,
display: none, visibility: hidden или
tabindex="-1".Чтобы скрыть элемент от навигации через Tab, можно использовать несколько подходов:
CSS-свойства
display: none; — полностью удаляет элемент из
визуального потока и исключает его из цикла табуляции.visibility: hidden; — скрывает элемент, но сохраняет
его пространство на странице. Tabbable также исключает такие
элементы.Атрибут tabindex
tabindex="-1" делает элемент доступным для фокуса
только программно (element.focus()), но исключает из
стандартной табуляции.tabindex="0" возвращает элемент в естественный порядок
табуляции.<button>Активная кнопка</button>
<button tabindex="-1">Скрытая от Tab</button>
import tabbable from "tabbable";
const visibleElements = tabbable(document.body);
console.log(visibleElements); // Содержит только активную кнопку
Интерфейсы часто требуют временного исключения элементов из табуляции без их удаления из DOM. Tabbable позволяет это сделать через манипуляцию атрибутами:
const button = document.querySelector("#dynamicButton");
// Скрыть от табуляции
button.setAttribute("tabindex", "-1");
// Вернуть в табуляцию
button.setAttribute("tabindex", "0");
Можно также комбинировать с классами и CSS для комплексного управления видимостью и доступностью.
Для сложных интерфейсов (модальные окна, раскрывающиеся списки, панели управления) важно учитывать:
display: none или
visibility: hidden, все дочерние элементы исключаются из
списка.disabled: кнопки и поля форм
с атрибутом disabled автоматически исключаются.Пример фильтрации только видимых элементов внутри модального окна:
const modal = document.querySelector("#modal");
const focusableInModal = tabbable(modal);
Этот подход гарантирует, что пользователь сможет перемещаться только по активным элементам интерфейса.
tabindex="-1" для временного
скрытия: проще, чем управлять классами и стилями, особенно при
динамических интерфейсах.aria-hidden="true"
для дополнительной доступности.Модальные окна, всплывающие подсказки и аккордеоны часто требуют блокировки табуляции за пределами активного компонента. Пример блокировки всего документа, кроме модального окна:
const modal = document.querySelector("#modal");
const allFocusable = tabbable(document.body);
const modalFocusable = tabbable(modal);
allFocusable.forEach(el => {
if (!modal.contains(el)) el.setAttribute("tabindex", "-1");
});
После закрытия модального окна атрибуты можно восстанавливать для возврата привычного порядка навигации.
Управление табуляцией через Tabbable обеспечивает гибкий контроль над пользовательским опытом, повышает доступность и предотвращает случайное фокусирование на скрытых или неактивных элементах. Такой подход особенно ценен в сложных интерфейсах с динамическими компонентами.