Библиотека Tabbable предназначена для определения
фокусируемых элементов на странице и управления последовательностью их
навигации с помощью клавиши Tab. При работе с
SVG-элементами необходимо учитывать специфику DOM SVG,
отличающуюся от HTML. SVG содержит графические элементы, такие как
<circle>, <rect>,
<path>, <text> и
<g>, которые по умолчанию не являются
фокусируемыми. Это влияет на поведение Tabbable, так как
библиотека ориентируется на стандартные HTML-элементы, поддерживающие
свойства tabindex и focusable.
Атрибут focusable В SVG версии 1.1
и выше существует атрибут focusable, который определяет,
может ли элемент принимать фокус. Его значения:
true — элемент может быть сфокусирован.false — элемент игнорируется при навигации.Пример:
<svg width="200" height="100">
<rect x="10" y="10" width="100" height="50" fill="blue" focusable="true" tabindex="0"></rect>
</svg>
Здесь <rect> становится доступным для Tabbable и
может быть частью таб-цепочки.
Атрибут tabindex Для интеграции SVG
в последовательность табуляции необходимо явно указывать
tabindex. Значения:
0 — элемент доступен в естественном порядке
табуляции.-1 — элемент можно сфокусировать программно, но не
через Tab.tabindex="0".Комбинация focusable="true" и tabindex="0"
делает SVG-элемент полностью совместимым с Tabbable.
Библиотека предоставляет методы tabbable() и
isTabbable() для работы с DOM-элементами. Для SVG их
применение требует учета фокусируемости:
import { tabbable } from 'tabbable';
const svgElement = document.querySelector('svg');
const focusableElements = tabbable(svgElement);
console.log(focusableElements);
Особенности:
tabindex или
focusable="true".<g> (группировка) Tabbable не будет
автоматически искать вложенные элементы, если сама группа не
фокусируемая. Необходимо либо добавить tabindex к
<g>, либо обрабатывать дочерние элементы
отдельно.disabled для <button> в
SVG-аналогах (например, <foreignObject> с
HTML-кнопкой) корректно учитывается Tabbable.SVG-элементы с tabindex поддерживают события
focus и blur. Это важно для создания
интерактивных графиков, карт и кнопок внутри SVG. Пример:
const rect = document.querySelector('rect');
rect.addEventListener('focus', () => {
rect.setAttribute('fill', 'red'); // визуальная подсветка
});
rect.addEventListener('blur', () => {
rect.setAttribute('fill', 'blue');
});
Tебательно, что без tabindex эти события не
сработают.
Если SVG находится внутри Shadow DOM:
tabindex и focusable должны быть
явно указаны для каждого SVG-элемента.tabbable() и ручного обхода querySelectorAll
для SVG-групп.focusable="true" и tabindex="0".<g> использовать с осторожностью —
лучше фокусировать дочерние элементы.tabbable() после добавления в DOM, иначе новые
элементы не будут учтены.stroke, fill,
opacity) или CSS внутри
<foreignObject>.focusable для
SVG 1.1 и SVG 2.0, особенно в Edge Legacy и IE11.clipPath и другими
декоративными элементами — они никогда не фокусируются.<text> могут вести себя непредсказуемо
без tabindex.При использовании UI-фреймворков (React, Vue, Svelte) SVG-фокусируемые элементы:
tabIndex (с большой буквы),
иначе JSX не интерпретирует атрибут корректно.:focus или слушать события
focus/blur для управления стилями SVG.Эти подходы обеспечивают корректное взаимодействие Tabbable с SVG и позволяют строить полностью клавиатурно-доступные графические интерфейсы.