Что такое tabbable

Библиотека Tabbable предназначена для определения элементов DOM, на которые пользователь может перейти с помощью клавиши Tab. В современном веб-разработке навигация с клавиатуры играет ключевую роль для доступности, особенно для пользователей с ограниченными возможностями. Tabbable упрощает идентификацию фокусируемых элементов, учитывая их видимость, состояние и правила браузера.

Tabbable работает с элементами, которые по стандарту HTML могут получать фокус, а также с пользовательскими элементами, если они соответствуют определённым условиям. Основной задачей библиотеки является фильтрация элементов по следующим критериям:

  • Элемент не скрыт (не имеет display: none, visibility: hidden или opacity: 0 при полной прозрачности).
  • Элемент не отключён (disabled).
  • Элемент имеет корректный tabindex (значение ≥ 0, либо отсутствует, что по умолчанию делает элемент фокусируемым).

Установка и подключение

Библиотека доступна через npm и легко интегрируется в проект:

npm install tabbable

Подключение в модульном Jav * aScript:

import { tabbable } from 'tabbable';

Функция tabbable() принимает DOM-элемент или его родителя и возвращает массив всех доступных для табуляции элементов.


Основные методы

tabbable(container, options)

  • container — DOM-узел, внутри которого происходит поиск фокусируемых элементов. Если не указан, можно использовать document.body.

  • options — объект с дополнительными параметрами:

    • includeContainer (boolean) — включает ли сам контейнер в результат, если он фокусируемый.
    • displayCheck (string) — способ проверки видимости элементов: "full" (по умолчанию) или "legacy".
    • getShadowRoot (function) — возвращает теневой корень для обхода веб-компонентов.

Пример использования:

const container = document.getElementById('form');
const focusableElements = tabbable(container);
console.log(focusableElements); // массив элементов

Ключевые особенности работы

  1. Обход теневых DOM и фреймов Tabbable корректно работает с Shadow DOM, если передать функцию getShadowRoot, которая возвращает корень. Это позволяет выявлять фокусируемые элементы внутри веб-компонентов.

  2. Поддержка tabindex

    • tabindex="0" — элемент фокусируемый, порядок следует естественной последовательности DOM.
    • tabindex>0 — элемент получает приоритет при навигации, помещается в начало очереди табуляции.
    • tabindex<0 — элемент исключается из естественной табуляции, доступен только программно (element.focus()).
  3. Фильтрация по стилю Элементы с display: none, visibility: hidden или полупрозрачностью (opacity: 0) не включаются в результат, что предотвращает попытки фокусировки на невидимых элементах.

  4. Совместимость с различными элементами Фокусируемыми считаются: <a href>, <button>, <input>, <select>, <textarea>, <iframe>, а также любые элементы с положительным tabindex.


Примеры использования

Навигация по форме:

const form = document.querySelector('#signupForm');
const focusable = tabbable(form);

focusable.forEach((el, index) => {
  el.addEventListener('keydown', (e) => {
    if (e.key === 'Tab') {
      const nextIndex = (index + 1) % focusable.length;
      focusable[nextIndex].focus();
      e.preventDefault();
    }
  });
});

Выбор фокусируемого элемента с приоритетом:

const modal = document.querySelector('#modal');
const focusables = tabbable(modal).sort((a, b) => {
  return (b.tabIndex || 0) - (a.tabIndex || 0);
});
focusables[0].focus(); // устанавливаем фокус на элемент с наивысшим tabindex

Советы по оптимальному использованию

  • Использовать внутри компонентов модального окна для реализации фокусного цикла.
  • Проверять, что элементы видимы и активны, перед добавлением их в список фокусируемых.
  • При работе с динамическим контентом вызывать tabbable() заново, так как DOM может изменяться.
  • Для улучшенной доступности комбинировать Tabbable с aria-атрибутами, такими как aria-hidden и aria-disabled.

Внутренние механизмы

  • Проверка видимости выполняется через getComputedStyle и свойства offsetWidth/offsetHeight.
  • Рекурсивный обход всех дочерних узлов позволяет учитывать вложенные контейнеры и скрытые элементы.
  • Обработка Shadow DOM через опциональный метод getShadowRoot позволяет библиотеке работать с современными веб-компонентами.
  • Сортировка элементов происходит сначала по tabindex > 0, затем по естественному DOM-порядку, обеспечивая предсказуемую навигацию.

Заключение по функциональности

Библиотека Tabbable предоставляет детализированный контроль над фокусируемыми элементами в DOM, учитывает все нюансы современных веб-технологий: видимость, состояние, Shadow DOM и пользовательские tabindex. Использование этой библиотеки повышает доступность интерфейсов, позволяет строить модальные окна, формы и сложные компоненты с корректной навигацией клавиатурой.