Порядок табуляции по умолчанию, обеспечиваемый позицией семантических элементов HTML в DOM, удобен, но иногда вам может потребоваться изменить порядок табуляции. Перемещение элементов в HTML — идеальный вариант, но может оказаться неосуществимым. В этих случаях вы можете использовать HTML-атрибут tabindex
, чтобы явно установить положение табуляции элемента.
tabindex
можно применить к любому элементу, хотя он не обязательно полезен для каждого элемента и принимает диапазон целочисленных значений. С помощью tabindex
вы можете указать явный порядок для фокусируемых элементов страницы, вставить в порядок табуляции элемент, который в противном случае не будет фокусироваться, и удалить элементы из порядка табуляции. Например:
tabindex="0"
: вставляет элемент в естественный порядок табуляции. Элемент можно сфокусировать, нажав Tab , а элемент можно сфокусировать, вызвав его метод focus()
.
tabindex="-1"
: удаляет элемент из естественного порядка табуляции, но элемент по-прежнему можно сфокусировать, вызвав его метод focus()
.
tabindex="5"
: любой tabindex больше 0
переводит этот элемент в начало естественного порядка табуляции. Если существует несколько элементов с tabindex больше 0
, порядок табуляции начинается с наименьшего значения, большего нуля, и идет вверх.
Это особенно актуально для невводных элементов, таких как заголовки, изображения или заголовки статей. Когда это возможно, лучше всего расположить исходный код так, чтобы последовательность DOM обеспечивала логический порядок табуляции. Если вы используете tabindex
, ограничьте его пользовательскими интерактивными элементами управления, такими как кнопки, вкладки, раскрывающиеся списки и текстовые поля; то есть элементы, для которых пользователь может ожидать ввода данных.
Добавляйте tabindex
только к интерактивному контенту. Даже если контент важен, например ключевое изображение, пользователи программ чтения с экрана смогут понять его, не добавляя фокуса.
Управляйте фокусом на уровне страницы
Иногда tabindex
необходим для обеспечения бесперебойной работы пользователя. Например, если вы создаете надежную одну страницу с разными разделами контента, где не весь контент виден одновременно. Это может означать, что навигационные ссылки изменяют видимый контент без обновления страницы.
В этом случае определите выбранную область контента, присвойте ей tabindex
-1
и вызовите ее метод focus
. Это гарантирует, что контент не будет отображаться в естественном порядке табуляции. Этот метод, называемый управлением фокусом , синхронизирует воспринимаемый пользователем контекст с визуальным контентом сайта.
Управление фокусом в компонентах
В некоторых случаях вам также необходимо управлять фокусом на уровне элемента управления, например, с помощью пользовательских компонентов.
Например, элемент select
может получить базовый фокус, но как только он окажется там, вы сможете использовать клавиши со стрелками, чтобы открыть дополнительные доступные для выбора параметры. Если вы создаете собственный элемент select
, важно воспроизвести это поведение, чтобы пользователи клавиатуры могли по-прежнему взаимодействовать с вашим элементом управления.
Понять, какое поведение клавиатуры следует реализовать, может быть сложно. В руководстве «Практика разработки доступных полнофункциональных интернет-приложений (ARIA)» перечислены типы компонентов и типы действий с клавиатуры, которые они поддерживают.
Возможно, вы работаете над пользовательскими элементами , напоминающими набор переключателей, но с вашим уникальным внешним видом и поведением.
<radio-group>
<radio-button>Water</radio-button>
<radio-button>Coffee</radio-button>
<radio-button>Tea</radio-button>
<radio-button>Cola</radio-button>
<radio-button>Ginger Ale</radio-button>
</radio-group>
Чтобы определить, какая поддержка клавиатуры им нужна, обратитесь к руководству ARIA Authoring Practices . Раздел 2 содержит список шаблонов проектирования, включая таблицу характеристик радиогрупп — существующего компонента, который наиболее точно соответствует вашему новому элементу.
Одним из распространенных вариантов поведения клавиатуры, которое должно поддерживаться, являются клавиши со стрелками вверх/вниз/влево/вправо. Чтобы добавить такое поведение к новому компоненту, мы используем метод, называемый перемещением tabindex .
Перемещающийся tabindex работает, устанавливая tabindex
в -1 для всех дочерних элементов, кроме активного в данный момент.
<radio-group>
<radio-button tabindex="0">Water</radio-button>
<radio-button tabindex="-1">Coffee</radio-button>
<radio-button tabindex="-1">Tea</radio-button>
<radio-button tabindex="-1">Cola</radio-button>
<radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>
Компонент использует прослушиватель событий клавиатуры, чтобы определить, какую клавишу нажимает пользователь; когда это происходит, он устанавливает tabindex
ранее сфокусированного дочернего элемента на -1, устанавливает tabindex
дочернего элемента, который должен быть сфокусирован, на 0 и вызывает для него метод фокуса.
<radio-group>
<!-- Assuming the user pressed the down arrow, we'll focus the next available child -->
<radio-button tabindex="-1">Water</radio-button>
<radio-button tabindex="0">Coffee</radio-button> // call .focus() on this element
<radio-button tabindex="-1">Tea</radio-button>
<radio-button tabindex="-1">Cola</radio-button>
<radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>
Когда пользователь достигает последнего (или первого, в зависимости от направления перемещения фокуса) дочернего элемента, фокус возвращается к первому (или последнему) дочернему элементу.
Попробуйте следующий пример. Проверьте элемент в DevTools, чтобы увидеть, как tabindex перемещается от одного радио к другому.
Модалы и ловушки клавиатуры
Лучше избегать ручного управления фокусом, так как это может привести к сложным ситуациям. Например, виджет автозаполнения, который пытается управлять фокусом и фиксирует поведение вкладки, но не позволяет пользователю покинуть ее, пока она не будет завершена. Это называется ловушкой клавиатуры , и это может очень расстраивать пользователя.
В разделе 2.1.2 WCAG говорится, что фокус клавиатуры никогда не должен фиксироваться или захватываться одним конкретным элементом страницы . Пользователь должен иметь возможность переходить ко всем элементам страницы и обратно, используя только клавиатуру.
Исключением из этого правила являются модальные окна. Однако вам все равно следует избегать использования tabindex
при создании модального окна. С помощью inert
вы можете гарантировать, что пользователи не смогут случайно взаимодействовать с элементом (намеренная ловушка клавиатуры). Используйте элемент <dialog>
, который по умолчанию является инертным, чтобы создать модальное окно для пользователей, блокируя при этом клики и вкладки за пределами модального окна. Это позволяет пользователю сосредоточиться на необходимом выборе.