Библиотека Tabbable предназначена для определения элементов на странице, которые могут получать фокус через клавишу Tab. Она позволяет создавать доступные интерфейсы и управлять фокусируемыми элементами в сложных компонентах, таких как модальные окна, всплывающие панели или динамически создаваемые списки.
В основе работы Tabbable лежит проверка свойств элементов DOM, влияющих на их доступность для фокусировки. Среди таких свойств ключевыми являются:
tabindexdisabledopacity и pointer-eventsЭти свойства напрямую влияют на результат работы методов библиотеки.
opacity на tabbable элементыСвойство CSS opacity определяет прозрачность элемента.
Значение 0 делает элемент полностью прозрачным, но не
удаляет его из потока документа. Это значит:
opacity: 0 визуально невидим, но
остается интерактивным: клики, фокус и события
JavaScript по-прежнему работают.opacity: 0.tabindex="-1" или CSS-свойство
display: none/visibility: hidden.Пример:
<button style="opacity: 0;">Скрытая кнопка</button>
Tabbable включит эту кнопку в список, потому что она видима с точки зрения DOM, даже если полностью прозрачна.
pointer-eventsСвойство pointer-events управляет реакцией элемента на
взаимодействие с мышью. Возможные значения:
auto — элемент реагирует на события как обычноnone — элемент игнорирует все указательные
события (клик, hover и т.д.)Особенности взаимодействия с Tabbable:
pointer-events: none не блокирует фокус через Tab по
умолчанию. Элемент всё ещё может быть фокусируемым с клавиатуры.opacity: 0 и динамическим управлением
DOM это свойство помогает создавать элементы, которые полностью
неинтерактивны для мыши, но остаются доступными через
клавиатуру, если это требуется для тестирования или специальных
сценариев.Пример:
<button style="pointer-events: none;">Кнопка без клика</button>
Эта кнопка не будет реагировать на мышь, но Tabbable её
обнаружит как фокусируемый элемент.
opacity и pointer-eventsСочетание этих свойств позволяет тонко управлять интерактивностью:
opacity: 0 + pointer-events: none
Элемент визуально скрыт и не реагирует на мышь, но остаётся фокусируемым
с клавиатуры.
opacity: 0 + pointer-events: auto
Элемент невидим, но кликабельный мышью.
opacity: 1 + pointer-events: none
Элемент видим, но полностью игнорирует мышь, фокус клавиатуры
сохраняется.
Для полного исключения элемента из Tabbable лучше комбинировать
display: none, visibility: hidden и
tabindex="-1".
Tabbable предоставляет несколько функций для работы с фокусируемыми элементами:
tabbable(container) — возвращает массив всех элементов
внутри container, которые могут быть достигнуты через
Tab.isTabbable(element) — проверяет конкретный элемент на
фокусируемость.focusable(container) — более широкий список, включает
элементы, доступные для программного фокуса, даже если они не входят в
последовательность Tab.Эти функции учитывают свойства opacity и
pointer-events следующим образом:
opacity: 0 — элемент по умолчанию
считается focusable, но может быть исключён через кастомные
фильтры.pointer-events: none — элемент
остаётся tabbable, но мышь не взаимодействует с ним.display: none или
visibility: hidden — полностью исключают элемент
из всех списков.Пример кода:
import { tabbable } from 'tabbable';
const container = document.getElementById('modal');
const focusableElements = tabbable(container);
focusableElements.forEach(el => {
console.log(el.tagName, el.tabIndex, el.style.opacity, el.style.pointerEvents);
});
opacity: 0 для скрытия интерактивных
элементов не гарантирует их недоступность для клавиатуры.tabindex.pointer-events можно использовать для временной
блокировки мыши, сохраняя доступность для клавиатурного управления.Эти механизмы позволяют создавать интерфейсы, которые корректно реагируют на фокус, соблюдают стандарты доступности и гибко управляют интерактивностью через CSS.