Работа с disabled элементами

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


Поведение disabled элементов

Элемент считается disabled, если у него установлен атрибут disabled:

<button disabled>Кнопка</button>
<input type="text" disabled>

Основные свойства таких элементов в контексте Tabbable:

  • Не включаются в список табуляции — функция tabbable() их игнорирует.
  • Не получают фокус через JavaScript с помощью element.focus(), если браузер корректно соблюдает стандарт.
  • Могут быть видимыми, но недоступными для интерактивного взаимодействия.

Это поведение соответствует стандарту HTML и рекомендациям доступности (ARIA).


Работа функции tabbable()

Функция tabbable(container) возвращает массив элементов внутри container, которые могут быть сфокусированы с клавиши Tab. Для элементов с disabled происходит автоматическая фильтрация. Например:

import tabbable from 'tabbable';

const elements = tabbable(document.body);
console.log(elements);

В этом списке не окажутся:

  • <button disabled>
  • <input disabled>
  • <sel ect disabled>
  • <textarea disabled>

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


Исключения и тонкости

  1. Контейнеры с атрибутом disabled Если <fieldset> имеет disabled, все вложенные элементы <input>, <select>, <textarea>, <button> автоматически считаются недоступными для табуляции, даже если у них нет собственного disabled.

    <fieldset disabled>
      <input type="text">
      <button>Кнопка</button>
    </fieldset>

    В этом случае tabbable() не вернет вложенные элементы.

  2. Стили pointer-events: none и visibility: hidden Хотя атрибут disabled влияет на поведение элементов, Tabbable также учитывает видимость и доступность через CSS:

    • Элементы с display: none или visibility: hidden не попадают в массив tabbable.
    • Атрибут disabled действует независимо от CSS, но сочетание с невидимыми элементами гарантирует полное исключение из навигации.
  3. Элементы с tabindex="-1" Даже если элемент не disabled, но имеет tabindex="-1", он исключается из последовательности табуляции. Если элемент одновременно disabled и имеет tabindex, фильтр Tabbable отдаст приоритет disabled.


Примеры фильтрации

<div>
  <button>Активная кнопка</button>
  <button disabled>Недоступная кнопка</button>
  <input type="text" disabled>
  <input type="text">
</div>
import tabbable fr om 'tabbable';

const focusableElements = tabbable(document.querySelector('div'));
console.log(focusableElements);
// Результат:
// [ <button>Активная кнопка</button>, <input type="text"> ]

Только элементы без disabled и с видимым отображением попадают в результат.


Программное управление disabled элементами

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

const button = document.querySelector('#myButton');
button.disabled = true;

const focusable = tabbable(document.body);

После установки disabled элемент автоматически исключается из массива tabbable без необходимости перезапускать библиотеку или применять дополнительные фильтры.


Особенности для сложных компонентов

Для кастомных компонентов (например, модальных окон, вкладок или выпадающих списков) важно учитывать:

  • Скрытые disabled элементы: даже если элемент визуально скрыт с помощью opacity: 0 или смещен за пределы экрана, Tabbable учитывает видимость через CSS, а disabled блокирует фокус.
  • Комбинация ARIA и disabled: для интерактивных ролей (role="button", role="menuitem") использование aria-disabled="true" позволяет сообщить скринридеру о недоступности, но не исключает элемент из табуляции. Tabbable реагирует только на нативный disabled.

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

  • Всегда использовать disabled для блокировки стандартных элементов, чтобы гарантировать корректную навигацию.
  • Для кастомных компонентов использовать сочетание aria-disabled="true" и контроля tabindex, если требуется сохранить визуальный элемент, но сделать его недоступным.
  • При динамическом изменении состояния интерфейса вызывать tabbable() заново, чтобы получить актуальный список доступных элементов.

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