Элементы с нестандартными атрибутами

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

В контексте элементов с нестандартными атрибутами важно понимать, что Tabbable не ограничивается только стандартными интерактивными тегами (<a>, <button>, <input>, <textarea>, <select>). Любой элемент может стать табулябельным при определённых условиях.


Определение табулябельности

Функция tabbable(element) возвращает массив всех элементов внутри element, которые считаются табулябельными. Библиотека использует следующие критерии:

  1. Элемент видим (offsetWidth > 0 и offsetHeight > 0), не скрыт через CSS display: none или visibility: hidden.
  2. Элемент не заблокирован (disabled не установлен).
  3. Элемент либо имеет естественную фокусируемость, либо атрибут tabindex.

Ключевой момент: нестандартные атрибуты, такие как data-focusable или role="button", могут использоваться совместно с tabindex, чтобы сделать элемент фокусируемым. Например:

<div data-focusable="true" tabindex="0">Фокусируемый див</div>

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


Атрибут tabindex

tabindex — основной инструмент для управления порядком фокусировки. Его значения:

  • 0 — элемент включен в естественный порядок табуляции.
  • Положительное число — элемент получает приоритет выше стандартного порядка. Использовать осторожно, так как это может нарушить предсказуемый поток фокуса.
  • Отрицательное число (-1) — элемент фокусируемый, но не включается в последовательность табуляции.

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

<div role="menuitem" tabindex="0">Меню 1</div>
<div role="menuitem" tabindex="1">Меню 2</div>
<div role="menuitem" tabindex="-1">Меню 3</div>

При вызове tabbable(document.body) будут возвращены только элементы с tabindex="0" и tabindex="1".


Работа с нестандартными элементами

Tabbable позволяет включать в выборку элементы с любыми тегами, если они удовлетворяют критериям:

  1. Наличие tabindex ≥ 0.
  2. Фокусируемая роль ARIA, например role="button" или role="link".
  3. Не скрытые элементы (CSS, hidden атрибут или aria-hidden="true" исключают элемент).

Пример с произвольными тегами и ARIA:

<section role="region" aria-label="Интерактивная секция">
  <div role="button" tabindex="0">Кнопка див</div>
  <span role="link" tabindex="0">Ссылка спан</span>
</section>

Библиотека корректно включит эти элементы в результат tabbable(section).


Фильтрация элементов

Для работы с сложными структурами можно использовать дополнительную фильтрацию через isTabbable:

import { tabbable, isTabbable } from 'tabbable';

const elements = document.querySelectorAll('[data-focusable]');
const focusableElements = Array.from(elements).filter(el => isTabbable(el));

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


Особенности с нестандартными атрибутами

  • data-атрибуты: позволяют пометить элементы для дальнейшей логики фокуса.
  • Роли ARIA: для экранных читалок и семантической фокусировки.
  • Комбинация tabindex и CSS: важно, чтобы элемент был видим. Например, opacity: 0 не исключает элемент, но display: none — исключает.

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

  1. Любой нестандартный интерактивный элемент должен иметь tabindex="0" или роль ARIA.
  2. Не использовать положительные tabindex без необходимости — это нарушает предсказуемый порядок.
  3. Для динамически добавляемых элементов использовать isTabbable для проверки перед фокусировкой.
  4. Проверять совместимость с CSS-свойствами, влияющими на видимость (display, visibility, opacity).

Взаимодействие с фреймворками

В React, Vue или Svelte нестандартные компоненты часто рендерятся как <div> или <span>. Чтобы сделать их табулябельными:

<div role="button" tabindex="0" onCl ick={handleClick}>Кнопка</div>
  • tabindex="0" делает элемент включенным в последовательность Tab.
  • role="button" обеспечивает правильную семантику и поддержку скринридеров.
  • Tabbable автоматически обнаружит такие элементы в DOM.

Вывод

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