Библиотека Tabbable предназначена для определения
фокусиуемых элементов на веб-странице. Она используется для улучшения
навигации с клавиатуры, тестирования доступности интерфейсов и
управления последовательностью табуляции. Основной задачей является
выявление элементов, на которые пользователь может переместить фокус с
помощью клавиши Tab.
Tabbable анализирует DOM и возвращает массив элементов, которые
считаются фокусируемыми. Ключевое различие — не все элементы с
атрибутом tabindex автоматически считаются доступными для
фокуса. На фокус влияют следующие факторы:
display: none,
visibility: hidden исключают элемент).disabled.tabindex (элемент исключается из
обычной последовательности табуляции, но может быть фокусирован
программно).Невалидные контейнеры — это элементы, которые сами могут содержать фокусируемые элементы, но не должны участвовать в процессе табуляции. Сюда относятся контейнеры, которые по дизайну не предназначены для прямого фокуса, либо элементы с нарушенной видимостью или интерактивностью.
Скрытые контейнеры Если контейнер или любой его
предок имеет display: none или
visibility: hidden, все его дочерние элементы автоматически
считаются невидимыми для Tabbable.
<div style="display: none;">
<button>Кнопка</button>
</div>
В этом примере кнопка не попадет в массив tabbable элементов.
Контейнеры с disabled Формы,
fieldset и отдельные элементы с атрибутом disabled
исключаются.
<fieldset disabled>
<input type="text" />
</fieldset>
Любые дочерние элементы внутри fieldset не будут
фокусируемыми.
Элементы с отрицательным tabindex
tabindex="-1" исключает элемент из стандартного потока
табуляции. Tabbable учитывает это при генерации
последовательности.
Элементы с CSS, блокирующим интерактивность
Например, pointer-events: none или opacity: 0
не всегда исключает элемент, но в сочетании с
visibility: hidden делает его недоступным для
фокуса.
Для проверки элементов, находящихся внутри потенциально невалидных контейнеров, Tabbable использует рекурсивный обход DOM. Алгоритм следующий:
Это обеспечивает корректную генерацию последовательности табуляции даже в сложных вложенных структурах.
Tabbable позволяет использовать кастомные фильтры, чтобы игнорировать определённые контейнеры или включать элементы с нестандартной интерактивностью:
import { tabbable } from 'tabbable';
const elements = tabbable(document.body, {
getShadowRoot: true,
includeContainer: false,
filter: (element) => {
// Игнорировать элементы внутри контейнера с классом .ignore
return !element.closest('.ignore');
}
});
Параметр includeContainer управляет тем, будут ли
считаться сами контейнеры фокусируемыми, если они соответствуют
правилам. Параметр getShadowRoot позволяет искать tabbable
элементы внутри Shadow DOM.
Невалидные контейнеры могут находиться внутри iframe или
Shadow DOM. Tabbable корректно работает с:
tabindex с осторожностью: отрицательные
значения исключают элемент из естественной последовательности.getShadowRoot: true для полноценной
работы.Эти правила обеспечивают корректное поведение клавиатурной навигации и повышают доступность интерфейса, предотвращая неожиданный фокус на скрытые или неинтерактивные элементы.