Фокус

Интерактивные элементы, включая элементы управления формой , ссылки и кнопки, по умолчанию доступны для фокусировки и вкладок. Элементы с вкладками являются частью последовательного порядка навигации по фокусу документа. Другие элементы инертны, то есть не интерактивны. С помощью атрибутов HTML можно сделать интерактивные элементы инертными и сделать инертные элементы интерактивными.

По умолчанию порядок фокуса навигации такой же, как и визуальный порядок, который соответствует порядку исходного кода. Существуют атрибуты HTML, которые могут изменить этот порядок, и свойства CSS, которые могут изменить визуальный порядок контента. Изменение порядка табуляции с помощью HTML или порядка визуального рендеринга с помощью CSS может навредить пользовательскому опыту.

Не изменяйте предполагаемый и фактический порядок табуляции с помощью CSS и HTML. Как показывают следующие два примера, порядок табуляции, отличающийся от визуально ожидаемого, сбивает с толку пользователей и ухудшает взаимодействие с ними.

В этом примере значение атрибута tabindex сделало порядок табуляции хаотичным:

В этом примере CSS создал расхождение между порядком табуляции и визуальным порядком контента:

flex-flow: row-reverse; декларация изменила визуальный порядок. Кроме того, к шестому слову «Это» было применено свойство порядка CSS, которое визуально переместило это слово. Последовательность табуляции — это порядок кода, который больше не соответствует визуальному порядку, что приводит к отключению пользователей клавиатуры.

Делаем инертные элементы интерактивными

Атрибуты contenteditable и tabindex , являющиеся глобальными атрибутами, могут быть добавлены к любому элементу, что делает их фокусируемыми в процессе. Фокусируемые элементы также можно сфокусировать с помощью мыши или указателя, установив атрибут autofocus или с помощью сценария, например, с помощью element.focus() .

Атрибут tabindex

Глобальный атрибут tabindex , представленный в атрибутах , позволяет элементам, которые в противном случае не смогли бы получить фокус, получить фокус, обычно с помощью клавиши Tab, отсюда и название.

Атрибут tabindex принимает в качестве значения целое число. Отрицательное значение делает элемент доступным для фокусировки, но не доступным для табуляции. Значение tabindex , равное 0 делает элемент доступным для фокусировки и табуляции, добавляя элемент, к которому он применяется, к последовательному порядку навигации по фокусу в порядке исходного кода. Значение 1 или больше делает элемент доступным для фокусировки и табуляции, но добавляет его к приоритетной последовательности табуляции, и, как мы видели выше, этого следует избегать.

На этой странице кнопка «Поделиться» <share-action> является настраиваемым элементом . tabindex="0" добавляет этот элемент, который обычно не фокусируется на фокусе, в порядок табуляции по умолчанию на клавиатуре:

<share-action authors="@front-end.social/@estellevw" data-action="click" data-category="web.dev" data-icon="share" data-label="share, mastodon" role="button" tabindex="0">
  <svg aria-label="share" role="img" xmlns="http://www.w3.org/2000/svg">
    <use href="#shareIcon" />
  </svg>
  <span>Share</span>
</share-action>

На этой странице есть еще один пользовательский элемент: в локальной навигации есть пользовательский элемент с отрицательным значением tabindex :

<web-navigation-drawer type="standard" tabindex="-1">

Атрибут tabindex с отрицательным значением делает элемент доступным для фокусировки, но не доступным для табуляции. Элемент способен получать фокус, например, через HTMLElement.focus() , но он не является частью последовательного порядка навигации по фокусу. Для элементов, не поддерживающих табуляцию и фокусируемых, принято использовать tabindex="-1" . Обратите внимание: если вы добавите tabindex="-1" к интерактивному элементу, он больше не будет доступен для вкладок.

Метод element.focus() можно использовать для установки фокуса на фокусируемые элементы. Обратите внимание, что браузеры прокручивают выделенные элементы в поле зрения. По этой причине избегайте использования element.focus({preventScroll:true}) , поскольку сосредоточение внимания на невидимом элементе приведет к ухудшению пользовательского опыта.

Если вы хотите запросить документ, чтобы узнать, какой элемент в данный момент находится в фокусе, используйте свойство Document.activeElement доступное только для чтения.

Элементы с tabindex , равным 1 или выше, включаются в отдельную последовательность табуляции. Как вы заметите в Codepen, переход по табуляции начинается в отдельной последовательности, в порядке от наименьшего значения к наибольшему, а затем проходит через обычные последовательности (без заданного tabindex или tabindex="0" ) в исходном порядке:

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

Атрибут contenteditable

Атрибут contenteditable обсуждался ранее. Установка contenteditable="true" для любого элемента делает его редактируемым, фокусируемым и включенным в порядок табуляции. Поведение фокуса аналогично настройке tabindex="0" , но не то же самое. Вложенные contenteditable элементы доступны для фокусировки, но не для вкладок. Чтобы сделать вложенный элемент contenteditable доступным для табуляции, добавьте tabindex="0" , что добавит его в порядок навигации с последовательным фокусом.

Уделение внимания интерактивным элементам

Атрибут autofocus

Хотя логический autofocus является глобальным атрибутом, который можно установить для любого элемента, он не делает инертный элемент интерактивным. Когда страница загружается, первый фокусируемый элемент с установленным атрибутом autofocus получит фокус, если этот элемент отображается, а не вложен в <dialog> .

Автоматическая установка фокуса на контенте может сбить с толку. Установка autofocus на элементе управления формой означает, что элемент управления формы будет прокручиваться в поле зрения при загрузке страницы. Все ваши пользователи, включая пользователей программ чтения с экрана и пользователей с маленькими окнами просмотра, могут не «видеть» инструкции для формы, возможно, даже прокручивая их мимо обычно видимой метки элемента управления формой. Атрибут autofocus не меняет порядок последовательной навигации по фокусу документа. Элементы в последовательности, предшествующие элементу с автофокусировкой, просто пропускаются. По этим причинам не рекомендуется включать атрибут autofocus .

Исключением из рекомендации «не использовать autofocus » является включение атрибута autofocus в элементы <dialog> . Когда диалоговое окно открывается, браузер автоматически фокусируется на первом интерактивном элементе, который можно фокусировать в <dialog> , что означает, что autofocus на элементе не требуется. Если вы хотите быть уверенным, что конкретный интерактивный элемент в диалоговом окне получит фокус при его открытии, добавьте к этому элементу атрибут autofocus .

<dialog open>
  <form method="dialog">
    <button type="submit" autofocus>close</button>
  </form>
</dialog>

Атрибут autofocus , установленный для <button> закрытия, гарантирует, что он получит фокус при открытии диалогового окна. Будучи первым элементом в диалоге, он в любом случае получил бы фокус. По умолчанию, когда диалоговое окно открывается, первый фокусируемый элемент в диалоговом окне получит фокус, если только для другого элемента в диалоговом окне не установлен атрибут autofocus .

Делаем интерактивные элементы инертными

Существуют также атрибуты HTML, которые могут удалять интерактивные элементы из последовательности табуляции. Включение отрицательного tabindex для фокусируемых элементов, добавление disabled атрибута для поддержки элементов управления формой и добавление глобального атрибута inert в контейнер — все это делает элементы недоступными для табуляции. Эти три атрибута НЕ являются взаимозаменяемыми.

Отрицательное значение tabindex

Как мы узнали выше, атрибут tabindex с отрицательным значением делает элемент доступным для фокусировки, но не для табуляции. При добавлении tabindex="0" к элементу, доступному по умолчанию, включая ссылки, кнопки, элементы управления формой и элементы, которые contenteditable нет необходимости; включение tabindex с отрицательным значением удаляет обычно табулируемые элементы из порядка навигации с последовательным фокусом.

Отрицательное значение tabindex не позволяет пользователям клавиатуры фокусироваться на интерактивных элементах, но не отключает элемент. Пользователи указателей по-прежнему могут сосредоточиться на элементе. Чтобы отключить элемент, используйте атрибут disabled .

Неполноценный

Логический атрибут отключен делает элементы управления формы, к которым он применяется, и их потомков, если таковые имеются, недоступными для фокусировки. Отключенные элементы управления формой не могут быть сфокусированы, не получают событий щелчка и не отправляются при отправке формы. Примечание disabled не является глобальным атрибутом. Это применимо к <button> , <input> , <optgroup> , <option> , <select> , <textarea> , пользовательским элементам, связанным с формой, и <fieldset> . Если установлено в <optgroup> или <fieldset> , все элементы управления дочерней формы отключаются, за исключением содержимого первого <legend> <fieldset> .

Те же элементы, которые поддерживают disabled также доступны для псевдоклассов :disabled и :enabled . Элементы, отключенные атрибутом disabled , обычно оформляются светло-серым цветом с помощью таблицы стилей пользовательского агента, даже если установлен accent-color .

Будучи логическим атрибутом, его наличие отключает включенный в противном случае элемент; вы не можете установить для него значение false . Чтобы повторно включить отключенный элемент, атрибут необходимо удалить, обычно с помощью Element.removeAttribute('disabled') .

Свойство HTMLInputElement.disabled позволяет проверить, отключен ли ввод. Поскольку disabled не является глобальным атрибутом, он не наследуется от HTMLElement, но каждый интерфейс вспомогательного элемента, например HTMLSelectElement , HTMLTextareaElement , имеет одно и то же свойство, доступное только для чтения.

Атрибут disabled не применяется к обычно inert элементам, которые становятся фокусируемыми с помощью tabindex или contenteditable . Это также не относится к самому элементу <form> . Чтобы отключить их, можно использовать глобальный атрибут inert .

inert атрибут

Когда к элементу добавляется глобальный логический атрибут inert , этот элемент и все вложенное содержимое становятся отключенными (ни кликабельными, ни вкладочными) и удаляются из дерева доступности. Хотя inert можно применить к любому элементу, обычно он используется для разделов контента, таких как закадровый или иным образом скрытый контент.

При применении disabled управления формы браузер обеспечивает стиль по умолчанию, и его можно стилизовать с помощью псевдокласса :disabled . Атрибут inert не предоставляет визуальных индикаторов и не имеет соответствующего псевдокласса (хотя селектор атрибута [inert] соответствует).

Использование inert для видимого контента без стилей, указывающих на инертность, может привести к ухудшению пользовательского опыта. Поскольку инертный контент недоступен для пользователей программ чтения с экрана, это может привести к путанице, когда зрячие пользователи программ чтения с экрана видят на экране контент, недоступный для инструментов специальных возможностей. Сделайте инертность заметной с помощью CSS.

Убедитесь, что фокус никогда не перемещается на невидимый контент. Все, что отображается за кадром и не попадает в поле зрения автоматически при фокусировке, должно быть сделано инертным . Если содержимое скрыто, но появляется в поле зрения при фокусировке, как, например , ссылка «Перейти к содержимому» на этой странице, его не нужно делать инертным.

Проверьте свое понимание

Проверьте свое понимание

Проверьте свои знания о фокусе.

Если элемент не может быть сфокусирован, это описывается как?

Пустой.
Скрытый.
Инертный.

Что будет верно, если элемент имеет disabled атрибут?

Это будет невозможно сфокусироваться.
Если это элемент формы, он не будет отправлен.
Оно не будет отображаться.