Основные концепции табуляции

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


Определение “tabbable” элементов

Tabbable элементы — это элементы, на которые пользователь может перемещаться с помощью клавиши Tab. К ним относятся:

  • <a> с атрибутом href
  • <button>
  • <input> (кроме type="hidden")
  • <select>
  • <textarea>
  • Элементы с tabindex="0" или положительным значением tabindex

Элементы с tabindex="-1" исключаются из порядка табуляции, хотя на них можно программно установить фокус.

Ключевой момент: Tabbable учитывает как стандартные интерактивные элементы, так и кастомные элементы с корректным tabindex.


Основные функции библиотеки

tabbable(container)

Возвращает массив всех tabbable элементов внутри указанного контейнера, в порядке их табуляции. Пример использования:

import tabbable from 'tabbable';

const container = document.querySelector('#form');
const tabbableElements = tabbable(container);
console.log(tabbableElements);

Особенности:

  • Игнорируются скрытые элементы (display: none, visibility: hidden).
  • Элементы с disabled не включаются.
  • Элементы с tabindex="-1" исключаются.

isTabbable(element)

Проверяет, является ли конкретный элемент tabbable. Возвращает true или false.

import { isTabbable } from 'tabbable';

const button = document.querySelector('button');
console.log(isTabbable(button)); // true

Примечание: Эта функция полезна для динамически создаваемых элементов и условной проверки доступности элементов.


focusable(element)

Функция focusable определяет, может ли элемент получить фокус вообще, независимо от порядка табуляции. Отличие от isTabbable заключается в том, что элементы с tabindex="-1" считаются фокусируемыми.

import { focusable } from 'tabbable';

const div = document.querySelector('#custom');
console.log(focusable(div)); // true, если div с tabindex="-1"

Вывод: focusable используется для настройки фокуса на элементы, которые не участвуют в обычной навигации клавишей Tab.


Обработка сложных сценариев

Складывающиеся панели и модальные окна

При открытии модальных окон важно ограничивать фокус только элементами внутри окна. Использование tabbable позволяет:

  1. Получить все tabbable элементы в модальном контейнере.
  2. Переключать фокус между ними при нажатии Tab/Shift+Tab.
  3. Избежать выхода фокуса за пределы модального окна.
const modal = document.querySelector('.modal');
const elements = tabbable(modal);
elements[0].focus(); // устанавливаем фокус на первый элемент

Совет: При закрытии модального окна фокус возвращается к элементу, который его открыл.


Управление кастомными компонентами

Компоненты с нестандартной структурой (например, кастомные селекты или списки) часто требуют программного управления фокусом:

  • Использование tabindex="0" для элементов, которые должны быть в порядке табуляции.
  • Элементы с tabindex="-1" можно фокусировать программно.
  • Проверка с помощью isTabbable перед установкой фокуса предотвращает ошибки.

Практические рекомендации

  • Все интерактивные элементы должны быть tabbable по умолчанию.
  • Для динамически генерируемого контента проверять tabbable элементы после рендеринга.
  • Использовать tabindex разумно: положительные значения изменяют естественный порядок табуляции и могут привести к непредсказуемому поведению.
  • В модальных диалогах и всплывающих меню ограничивать фокус только видимыми и tabbable элементами.

Отличие tabbable от нативного document.activeElement

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


Взаимодействие с CSS и стилями

Tabbable учитывает CSS-свойства, влияющие на видимость:

  • display: none — элемент не tabbable
  • visibility: hidden — элемент не tabbable
  • opacity: 0 — элемент может быть tabbable, если он видим для скринридеров
  • pointer-events: none — не влияет на tabbable, но блокирует взаимодействие мышью

Это позволяет точно контролировать, какие элементы должны участвовать в навигации клавишей Tab.


Интеграция с фреймворками

В современных фреймворках (React, Vue, Angular) Tabbable применяется для:

  • Управления фокусом при динамическом рендеринге компонентов.
  • Создания доступных форм, модальных окон и вкладок.
  • Автоматической фильтрации скрытых или отключённых элементов.

Использование библиотеки совместимо с виртуальными DOM, так как методы работают с реальными DOM-элементами после их рендеринга.


Итоговые ключевые моменты

  • Tabbable позволяет определить элементы, доступные для навигации клавишей Tab.
  • Основные функции: tabbable(container), isTabbable(element), focusable(element).
  • Позволяет управлять фокусом в модальных окнах, сложных компонентах и динамически создаваемом контенте.
  • Учитывает CSS-свойства и атрибуты, влияющие на доступность элементов.
  • Обеспечивает предсказуемую и корректную навигацию по интерфейсу.