Aria-атрибуты и роли

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

В основе работы Tabbable лежит определение т.н. “tabbable elements” — элементов, которые браузер воспринимает как доступные для фокусировки. Это включает:

  • интерактивные элементы (<button>, <input>, <select>, <textarea>, <a> с href),
  • элементы с атрибутом tabindex="0" или положительным значением,
  • элементы, видимые и не отключённые через disabled или aria-hidden="true".

Проверка видимости и состояния элемента

Tabbable учитывает не только HTML-разметку, но и стили CSS, влияющие на видимость элемента. Ключевые моменты:

  • Элемент с display: none или visibility: hidden исключается из списка.
  • Элемент с disabled также считается недоступным для фокуса.
  • Элементы внутри aria-hidden="true" игнорируются библиотекой, так как они воспринимаются вспомогательными технологиями как недоступные.

Это важно для динамических интерфейсов, где блоки контента могут показываться или скрываться программно.

Работа с атрибутами tabindex

Атрибут tabindex контролирует порядок фокусировки:

  • tabindex="0" — элемент доступен в естественном порядке документа.
  • Положительное значение tabindex="1", tabindex="2" и т.д. — элемент получает приоритет перед элементами с tabindex="0".
  • tabindex="-1" — элемент становится фокусируемым программно, но не через клавишу Tab.

Tabbable корректно обрабатывает эти значения, формируя массив элементов в правильной последовательности, включая сочетание положительных, нулевых и скрытых элементов.

Интеграция с ARIA-атрибутами и ролями

ARIA (Accessible Rich Internet Applications) используется для улучшения взаимодействия с вспомогательными технологиями. Tabbable учитывает некоторые из этих атрибутов при выборе элементов:

  • role="button", role="link", role="textbox" и другие интерактивные роли делают элемент потенциально фокусируемым, если они видимы.
  • Атрибут aria-disabled="true" не полностью совпадает с disabled, но библиотеки типа Tabbable могут игнорировать такие элементы в зависимости от настроек.
  • Атрибут aria-hidden="true" исключает элемент и его потомков из списка tabbable, что важно при модальных окнах и динамических панелях.

Применение ARIA-атрибутов позволяет создать интерфейс, где фокус корректно перемещается даже на кастомные компоненты, реализованные с помощью <div> или <span>.

Основные методы библиотеки

Tabbable предоставляет два основных метода:

  1. tabbable(container) — возвращает массив элементов, доступных для фокуса в контейнере, учитывая порядок табуляции.
  2. isTabbable(element) — проверяет, можно ли элемент сфокусировать через Tab.

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

import { tabbable, isTabbable } from 'tabbable';

const container = document.querySelector('#form');
const focusableElements = tabbable(container);

focusableElements.forEach(el => {
  console.log(el.tagName, el.tabIndex);
});

const button = document.querySelector('#submit');
console.log(isTabbable(button)); // true или false

Эти методы обеспечивают динамическую проверку фокусируемых элементов, что особенно важно при создании модальных диалогов, кастомных виджетов и интерактивных списков.

Модальные окна и управление фокусом

В модальных окнах или всплывающих панелях важно ограничивать фокус только элементами внутри окна. Tabbable позволяет:

  • Получить все tabbable-элементы внутри модального контейнера.
  • Организовать цикл фокуса, чтобы Tab и Shift+Tab не уходили за пределы модального окна.
  • Исключить элементы, скрытые за помощью aria-hidden или display: none.

Пример реализации циклического фокуса:

const modal = document.querySelector('#modal');
const elements = tabbable(modal);
let first = elements[0];
let last = elements[elements.length - 1];

modal.addEventListener('keydown', e => {
  if (e.key === 'Tab') {
    if (e.shiftKey && document.activeElement === first) {
      e.preventDefault();
      last.focus();
    } else if (!e.shiftKey && document.activeElement === last) {
      e.preventDefault();
      first.focus();
    }
  }
});

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

  • Все интерактивные кастомные элементы должны иметь ARIA-роль, соответствующую поведению (role="button", role="checkbox" и т.д.).
  • Для элементов, скрытых визуально, использовать aria-hidden="true" вместо display: none, если необходим контроль через скрипт.
  • При динамическом изменении интерфейса всегда пересчитывать tabbable-элементы, чтобы избежать “залипания” фокуса.
  • Для сложных виджетов с кастомной логикой фокуса использовать tabindex и ARIA совместно с библиотекой Tabbable.

Взаимодействие с кастомными компонентами

Кастомные элементы (<div>, <span>) можно сделать tabbable, добавив:

<div role="button" tabindex="0">Click me</div>
  • role="button" — сообщает вспомогательным технологиям, что элемент ведет себя как кнопка.
  • tabindex="0" — позволяет перемещать фокус с клавиатуры.

Tabbable корректно включит этот элемент в массив tabbable, что обеспечивает предсказуемую навигацию по интерфейсу.


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