Перейти к основному содержимому

Доступная Карусель: Пошаговое руководство

Информация о статье

Последнее обновление:

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

Здесь вы видите пример полностью доступной карусели:

Базовая структура для Карусели

Вся карусель должна быть распознаваема как отдельный регион на странице [1]. Без такой разметки пользователям, которые навигируются с помощью ориентиров (Landmarks), сложно ее найти, и ее назначение остается неясным [2].

Открыть текстовое описание «Схематическое представление базовой структуры доступной карусели»

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

  1. Основная область: Секция с уникальным идентификатором и атрибутом aria-roledescription.

  2. Заголовок: Заголовок с уникальным идентификатором, связанный с основной областью через aria-labelledby.

  3. Список слайдов: Список, содержащий слайды.

    • Слайды: Каждый слайд — это элемент списка, который содержит собственное содержимое (например, в элементе article). Скрытые слайды помечены как aria-hidden="true".
  4. Элементы управления:

    • Список кнопок-стрелок (для последовательной навигации).
    • Радиогруппа с точками (для прямого выбора).
    • Кнопка паузы (для управления автоматическим пролистыванием).
    • Область для статусных сообщений (для скринридера).

Здесь я показываю пример базовой структуры:

Базовая HTML-структура региона Карусели
<section
id="carousel-section"
class="carousel"
aria-roledescription="Карусель"
aria-labelledby="carousel-heading"
>
<h2 id="carousel-heading">Актуальные предложения</h2>
</section>

Мы помещаем карусель в элемент <section> [1]. С помощью aria-labelledby [3] вы указываете на видимый заголовок (тот, что <h2>), что делает <section> именованным регионом. aria-roledescription="Карусель" [4] сообщает скринридеру, что это такое (а именно 'Карусель'), и это должно быть сделано на языке пользователя [5].

Контрольный список для базовой структуры:

  • Вы обернули карусель в элемент <section> [1] с aria-roledescription="Карусель" [4] для описания скринридером?
  • Если ваш сайт многоязычен, локализовано ли значение aria-roledescription на языке пользователя? [5]
  • Имеет ли ваша карусель заголовок с уникальным ID? [6]
  • Имеет ли секция карусели атрибут aria-labelledby, который ссылается на ID заголовка? [3]

Контейнер для Слайдов

Слайды — это группа элементов, которые принадлежат друг другу. Поэтому вы должны разметить их как список [7]. Если вы просто поместите слайды в <div>, скринридеры не смогут распознать ни количество слайдов, ни понять, как они связаны между собой [8].

Вот пример структуры контейнера для слайдов:

HTML-структура контейнера для слайдов в виде списка
<ul class="slides-container" aria-label="Слайды">
<li></li>
<li></li>
</ul>

Вы структурируете слайды как элементы списка (<li>) в неупорядоченном списке (<ul>) [7]. Таким образом, скринридеры могут распознать количество слайдов и понять их взаимосвязь [8].

Контрольный список для контейнера слайдов:

  • Находятся ли ваши слайды карусели в элементе <ul>, при этом каждый слайд заключен в элемент <li>? [7], [8]
  • Имеет ли элемент <ul> атрибут aria-label, описывающий список слайдов [9]?

Содержимое Слайдов

Каждый слайд вы должны строить как отдельный раздел с четкой структурой и корректными ARIA-атрибутами, чтобы его роль и позиция в карусели были ясны [8].

Вот пример структуры слайдов в карусели:

HTML-структура отдельного слайда с ARIA-атрибутами
<ul class="slides-container" aria-label="Слайды">
<li>
<article
class="slide active"
id="slide-1"
aria-roledescription="Слайд"
aria-labelledby="slide-heading-1"
aria-posinset="1"
aria-setsize="3"
aria-hidden="false"
tabindex="-1"
>
<h3 id="slide-heading-1" tabindex="-1">
Эксклюзивное Летнее Предложение
</h3>
<p>Откройте для себя наши новые летние коллекции со скидкой до 30%.</p>
<a href="#" class="cta-button">
<span class="visually-hidden">Эксклюзивное Летнее Предложение — </span
>Узнать больше
</a>
</article>
</li>

<li>
<article
class="slide"
id="slide-2"
aria-roledescription="Слайд"
aria-labelledby="slide-heading-2"
aria-posinset="2"
aria-setsize="3"
aria-hidden="true"
tabindex="-1"
inert
>
<h3 id="slide-heading-2" tabindex="-1">
Новинка: Наше Снаряжение для Активного Отдыха
</h3>
<p>
Идеально подходит для вашего следующего приключения на природе. Прочное
и долговечное.
</p>
<a href="#" class="cta-button">
<span class="visually-hidden"
>Новинка: Наше Снаряжение для Активного Отдыха — </span
>Узнать больше
</a>
</article>
</li>
</ul>

Содержимое каждого слайда находится в элементе <article>, что придает ему семантическую структуру [1]. Каждый <article> должен иметь атрибуты aria-roledescription="Слайд" [4], aria-posinset и aria-setsize [8].

Таким образом вы сообщаете роль и позицию. Вы делаете это потому, что некоторые браузеры и скринридеры не распознают aria-posinset и aria-setsize автоматически из списка <ul>, особенно если вы динамически меняете слайды или CSS искажает список. Скрытые слайды вы помечаете aria-hidden="true" и inert, чтобы они исчезли из Дерева Доступности (Accessibility Tree) [10].

Контрольный список для содержимого слайдов:

  • Вы поместили содержимое слайда в элемент <article>, чтобы обеспечить семантическую структуру? [1]
  • Имеет ли каждый слайд атрибут aria-roledescription="Слайд", чтобы объявить его описание для скринридеров? [4]
  • Если ваш сайт многоязычен, локализовано ли значение aria-roledescription на языке пользователя? [5]
  • Имеет ли каждый слайд заголовок с уникальным ID [6]?
  • Имеет ли каждый слайд атрибут aria-labelledby, который ссылается на ID заголовка, чтобы сделать его именованным регионом [3]?
  • Имеет ли каждый слайд атрибуты aria-posinset и aria-setsize, чтобы дополнительно сообщить его позицию и общее количество слайдов? [8]
  • Отмечены ли скрытые слайды атрибутами aria-hidden="true" и inert или display: none, чтобы предотвратить их объявление скринридерами или взаимодействие с ними пользователями клавиатуры? [10]

Управление Фокусом

Аккуратное управление фокусом гарантирует, что пользователи знают свое местоположение при смене слайда [11]. Это критически важно для всех, кто использует вспомогательные технологии.

Пример фокуса на заголовке с синей рамкой
Пример фокуса на заголовке

После каждой ручной смены слайда вы должны установить фокус с помощью скрипта на первый элемент нового слайда (например, на заголовок внутри слайда) [12].

Открыть текстовое описание «Логика управления фокусом после смены слайда»

Эта блок-схема описывает шаги, необходимые для корректного управления фокусом после ручной смены слайда в карусели.

  1. Пользователь инициирует переключение (например, «Пользователь нажимает „Далее“»).
  2. JavaScript-событие запускает смену слайда («JavaScript-событие: начать смену слайда»).
  3. Выполняется визуальная анимация («Анимация выполняется»).
  4. Анимация завершается («Анимация завершена»).
  5. Новый слайд программно помечается как активный («Новый слайд помечается активным (.active)»).
  6. Ищется первый фокусируемый элемент нового слайда (например, заголовок <h3>) («Найти первый фокусируемый элемент»).
  7. Фокус устанавливается на этот элемент методом .focus() («Установить фокус через .focus()»).
  8. Экранный диктор зачитывает содержимое нового слайда («Скринридер зачитывает содержимое нового слайда»).

Вот фрагмент, как это может выглядеть в JavaScript:

JavaScript: Установка фокуса после смены слайда
// Пример логики после перехода к новому слайду
const newSlide = document.querySelector('.slide.active');
const focusableElement = newSlide.querySelector('h3');
focusableElement.focus();

Контрольный список для управления фокусом:

  • Перемещается ли фокус после нажатия на кнопку навигации на заголовок текущего слайда, чтобы его мог объявить скринридер? [12], [11]
  • Когда происходит смена слайда, перемещается ли фокус на новый слайд только после завершения анимации смены, а не раньше, чтобы избежать прерывания объявления? [13]

Управление Автоматической Ротацией

Ротация, которую вы не можете контролировать, сильно отвлекает и не дает людям достаточно времени, чтобы прочитать содержимое. Это прямое нарушение WCAG [14]. Поэтому все карусели с авторотацией должны соответствовать следующим требованиям:

  1. Кнопка Пауза/Воспроизведение: Вам нужна видимая и управляемая с клавиатуры кнопка для остановки и возобновления анимации [15]. Ее aria-label должен динамически меняться (например, "Остановить анимацию" / "Запустить анимацию").
    Пример кнопки для управления автоматической ротацией с иконкой паузы перед слайдами карусели
    Пример кнопки для управления автоматической ротацией
  2. Пауза при взаимодействии: Ротация должна автоматически приостанавливаться, как только вы наводите мышь на карусель (mouseenter) или фокусируете элемент внутри нее (focusin) [14].
  3. Уважение prefers-reduced-motion: Анимация должна быть деактивирована с самого начала, если пользователь установил в своей операционной системе предпочтение уменьшенного движения.

Открыть текстовое описание «Состояния автоматического вращения»

Эта диаграмма состояний показывает различные состояния автоматического вращения карусели и переходы между ними.

  • Начальное состояние — Idle (вращение выключено).

  • Из состояния Idle система переходит в AutoRotate (вращение активно) при выполнении действия «Запустить вращение».

  • Из состояния AutoRotate система может перейти в два других состояния:

    • В Paused (приостановлено) при действиях «Щелчок по кнопке паузы» или «Фокус или курсор наведён на карусель».
    • В RespectReducedMotion (уменьшенное движение) при действии «активирован prefers-reduced-motion».
  • Из состояния Paused система возвращается в AutoRotate при действии «Щелчок по кнопке воспроизведения».

  • Состояние RespectReducedMotion при необходимости возвращается в Paused.

Кроме того, автоматическая ротация должна приостанавливаться при взаимодействии с каруселью:

Контрольный список для управления автоматической ротацией:

  • Есть ли возможность остановить автоматическую ротацию, например, кнопка "Пауза"? [14], [15]
  • Реализована ли кнопка для автоматической ротации как элемент <button> [10] с атрибутами aria-label [9] и title [16] для объявления скринридером и всплывающих подсказок?
  • Имеет ли кнопка для автоматической ротации атрибут aria-pressed, чтобы указывать ее состояние (вкл/выкл), с соответствующим обновлением меток и заголовков? [17]
  • Фокусируется ли кнопка для автоматической ротации и можно ли управлять ею с клавиатуры (через Enter или Пробел)? [18]
  • Имеет ли кнопка для автоматической ротации различимый стиль фокуса [19] с коэффициентом контрастности не менее 3:1 к фону? [20]
  • Имеет ли кнопка для автоматической ротации коэффициент контрастности не менее 3:1 к фону для видимости? [20]
  • Имеет ли кнопка для автоматической ротации достаточный размер (минимум 44x44 пикселя) для облегчения взаимодействия? [21]
  • Останавливается ли автоматическая ротация, когда вы наводите мышь на текущий слайд или фокусируете его, чтобы обеспечить непрерывное взаимодействие с содержимым? [14]
  • Останавливается ли автоматическая ротация, когда на одну из кнопок управления слайдами карусели наводится мышь или она получает фокус? [14]
  • Уважает ли автоматическая ротация настройку пользователя prefers-reduced-motion и отключает ли анимации соответствующим образом? [14]

Кнопки-стрелки

С помощью кнопок-стрелок вы перемещаетесь по карусели. Кнопки "Далее" и "Назад" вы должны реализовать как настоящие кнопки. Слишком часто я вижу, как для этого злоупотребляют тегами <a> с href="#". Это семантически неверно [22], ненадежно работает с клавиатурой (особенно в Safari) и не активируется пробелом [18]. Поэтому: используйте элементы <button>. Важно, чтобы вы четко их обозначили и сделали доступными [10].

Пример кнопок-стрелок с иконками стрелок влево и вправо
Пример кнопок-стрелок

Вот пример структуры кнопок-стрелок:

HTML-структура для навигации стрелками
<ul class="carousel-navigation" aria-label="Последовательная Навигация">
<li>
<button
type="button"
id="prev-btn"
class="carousel-btn"
aria-label="Предыдущий Слайд"
title="Предыдущий Слайд"
></button>
</li>
<li>
<button
type="button"
id="next-btn"
class="carousel-btn"
aria-label="Следующий Слайд"
title="Следующий Слайд"
></button>
</li>
</ul>

Мы используем нативные элементы <button>. Они по умолчанию фокусируемы и управляемы [18]. aria-label [9] дает им доступное имя, описывающее их функцию (например, "Следующий Слайд"). Иконки (SVG или <img>) вы скрываете с помощью aria-hidden="true", так как они являются только декором [23].

Контрольный список для кнопок-стрелок:

  • Реализованы ли ваши кнопки навигации стрелками как элемент <ul> [7] с атрибутом aria-label [9] для описания элементов управления?
  • Расположены ли кнопки навигации стрелками последовательно в начале или в конце карусели перед точечной навигацией для легкого доступа? [24]
  • Реализованы ли кнопки навигации стрелками как элементы <button> [10] с атрибутами aria-label [9] и title [16] для объявления скринридером и всплывающих подсказок, если у них нет видимых текстовых меток?
  • Фокусируются ли кнопки навигации стрелками и можно ли управлять ими с клавиатуры (через Enter или Пробел)? [18]
  • Имеют ли кнопки навигации стрелками различимый стиль фокуса [19] с коэффициентом контрастности не менее 3:1 к фону? [20]
  • Имеют ли кнопки навигации стрелками коэффициент контрастности не менее 3:1 к фону для видимости? [20]
  • Имеют ли кнопки навигации стрелками достаточный размер (минимум 44x44 пикселя) для облегчения взаимодействия? [21]
  • Если кнопки-стрелки используют иконки, являются ли эти иконки декоративными и помечены ли они aria-hidden="true"? [23]

Точечная навигация

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

Пример точечной навигации с четырьмя точками под слайдами карусели, где вторая точка выделена как активная
Пример точечной навигации

Здесь речь идет не просто о клике, а о выборе опции из группы. Если вы реализуете это как простые <div> или <button>, будет отсутствовать семантика группы выбора [8], в которой может быть выбран только один вариант. Клавиатурная навигация с помощью стрелок тогда не работает [18], и текущее состояние также не сообщается [10].

Семантически наиболее чистое и надежное решение — реализовать это как группу радиокнопок (Radio-Button-Gruppe). Радиокнопки по умолчанию обеспечивают правильную семантику [10] и клавиатурную навигацию.

  • Вы помещаете группу в <fieldset> с <legend> [25], чтобы обозначить группу выбора.
  • Каждая точка — это <input type="radio"> с соответствующим <label> [26].
  • Чтобы вы могли это стилизовать, вы визуально скрываете настоящие радиокнопки (visually-hidden) и оформляете элементы <label> как кликабельные точки.
  • Чтобы скринридеры не читали оба элемента (двойное объявление), input получает четкий aria-label (например, "Слайд 1") [9], а <label> вы скрываете с помощью aria-hidden="true" для скринридеров.

Вот пример структуры точечной навигации:

HTML-структура для точечной навигации в виде Радио-группы
<fieldset class="carousel-dots">
<legend class="visually-hidden">Выбор Слайда</legend>

<input
type="radio"
id="dot-1"
name="carousel-dots"
class="visually-hidden"
aria-label="Слайд 1"
checked
/>
<label for="dot-1" class="carousel-dot-label" aria-hidden="true">
<span class="visually-hidden">Слайд 1</span>
</label>

<input
type="radio"
id="dot-2"
name="carousel-dots"
class="visually-hidden"
aria-label="Слайд 2"
/>
<label for="dot-2" class="carousel-dot-label" aria-hidden="true">
<span class="visually-hidden">Слайд 2</span>
</label>
</fieldset>

Контрольный список для точечной навигации:

  • Размещены ли точки навигации в элементе <fieldset> с соответствующим элементом <legend>, чтобы обеспечить метку, которая будет объявлена скринридерами? [25], [8]
  • Реализованы ли точки навигации как радиокнопки [10] для поддержки выбора и клавиатурной навигации (например, стрелками)? [18]
  • Поддерживают ли точки навигации клавиши Home и End для перехода к первому и последнему слайду, а также, опционально, клавиши ArrowDown и ArrowUp для навигации к следующему/предыдущему слайду? [18]
  • Имеют ли точки навигации атрибут aria-label [9] или соответствующую текстовую метку [26] для объявления скринридером?
  • Визуально различимы ли точки навигации при фокусировке [19], со стилем фокуса, который имеет минимальный коэффициент контрастности 3:1 к фону? [20]
  • Визуально выделена ли текущая активная точка и объявляется ли она скринридерами? [10]
  • Является ли текущая активная точка программно различимой? [10]

Объявление Смены Слайдов для Скринридеров

Когда пользователь вручную меняет слайд с помощью кнопок-стрелок, он пока не получает обратной связи о том, какой слайд активен.

Для этого нам нужен "Живой Регион" (Live Region), который объявляет об изменениях [13]. Визуально скрытый элемент с aria-live="polite" и aria-atomic="true" вы заполняете с помощью JavaScript новым статусом (например, "Слайд 2 из 3"). Это должно быть передано как сообщение о статусе. Важно: Делайте это только при ручной смене с помощью кнопок-стрелок, чтобы избежать информационной перегрузки при автоматической ротации или осознанном выборе с помощью точек.

Вот пример Живого Региона:

HTML-структура Живого Региона для сообщений о статусе
<div
id="slide-change-region"
class="visually-hidden"
role="status"
aria-live="polite"
aria-atomic="true"
></div>

Контрольный список для объявления смены слайдов:

  • Существует ли визуально скрытый элемент с aria-live="polite" и aria-atomic="true", который объявляет текущий статус слайда (например, "Слайд 2 из 5")? [13]
  • Имеет ли Живой Регион role="status", чтобы информировать скринридеры о том, что это сообщение о статусе? [28]
  • Активируется ли объявление Живого Региона после того, как фокус перемещен на новый слайд, чтобы гарантировать, что скринридер корректно и без прерывания объявит содержимое? [13]
  • Избегаете ли вы объявления текущего слайда во время автоматической ротации, так как пользователь не выполняет активной навигации? [13]
  • Обновляется ли Живой Регион только при ручной смене слайдов (например, с помощью кнопок-стрелок), чтобы избежать информационной перегрузки? [13]

Визуальный и Клавиатурный Фокус

Критически важно, чтобы все ваши интерактивные элементы имели четкий визуальный индикатор фокуса [19]. Это очень помогает пользователям клавиатуры и скринридеров.

Пример стиля фокуса с синей рамкой вокруг кнопки со стрелкой влево
Пример стиля фокуса

Контрольный список для визуального и клавиатурного фокуса:

  • Имеют ли все интерактивные элементы управления (точки навигации, кнопки-стрелки, кнопка паузы) различимый стиль фокуса [19] с коэффициентом контрастности не менее 3:1 к фону? [20]
  • Имеют ли все интерактивные элементы управления (точки навигации, кнопки-стрелки, кнопка паузы) коэффициент контрастности не менее 3:1 к фону для видимости? [20]

Инструкции по Доступному Взаимодействию

Если вы предоставляете инструкции по взаимодействию с каруселью [29], вы улучшаете доступность, поскольку даете ориентацию пользователям вспомогательных технологий.

Пример визуально скрытой инструкции по взаимодействию с каруселью, которую зачитывает VoiceOver
Пример визуально скрытой инструкции по взаимодействию с каруселью, которую зачитывает VoiceOver

Контрольный список для инструкций по взаимодействию:

  • Есть ли в карусели текстовый элемент, содержащий инструкции по взаимодействию? Вы можете его визуально скрыть. [29]
  • Связана ли инструкция с каруселью через aria-describedby, чтобы она объявлялась при фокусировке карусели? [30]
  • Связана ли инструкция с каждым слайдом через aria-describedby, чтобы она объявлялась при фокусировке слайда? [30]

Заключение

Доступные карусели — это не "приятное дополнение", а жесткое требование для инклюзивного пользовательского опыта и соблюдения требований WCAG 2.2. Надеюсь, это руководство показывает, что доступность не сводится к небольшой косметике: она возникает из семантически корректной структуры [8], полной управляемости с клавиатуры [18], надежного управления фокусом [11], контролируемой анимации [14], четких сообщений о статусе [13] и продуманного руководства пользователя.

Ключевой момент: карусели — это сложные, интерактивные компоненты со множеством состояний. Только сочетание структуры ориентиров (то есть section с именованным заголовком [2]), четкого описания роли (aria-roledescription [4]), видимых и программно распознаваемых состояний (например, активный слайд, приостановленная ротация) [10], а также надежных навигационных паттернов (кнопки вместо злоупотребления ссылками [22], радио-группа для точек [25]) позволяет вспомогательным технологиям надежно передавать взаимодействие.

На практике также важны Прогрессивное улучшение (убедитесь, что оно работает хотя бы грубо без JavaScript), Интернационализация (локализованные метки, особенно aria-roledescription) [5], Уважение системных предпочтений (prefers-reduced-motion) [14] и проверяемый тестовый дизайн. Систематически внедряя эти аспекты, вы устраняете барьеры, повышаете удовлетворенность всех пользователей и в долгосрочной перспективе снижаете свои расходы на обслуживание и поддержку.

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

Часто задаваемые вопросы (FAQ) о доступных каруселях

Почему управление фокусом так важно для каруселей?

Управление фокусом гарантирует, что вспомогательные технологии, такие как скринридеры, могут объявить новый слайд при его смене, и вам не придется вручную перемещаться к нему. Это критически важно для пользователей, которые полагаются на клавиатурную навигацию или скринридеры для понимания содержимого карусели [11].

Как я могу проверить, доступна ли моя карусель?

Тестирование — это настоящий вызов, так как автоматизированные инструменты, такие как WAVE или Axe, часто не в состоянии полностью оценить динамическое содержимое, такое как карусели. Вы должны тестировать вручную: проверять клавиатурную навигацию (Tab, стрелки, Enter) [18], проверять объявления скринридеров (например, VoiceOver, JAWS) [10] и убедиться, что вы можете управлять всеми интерактивными элементами без мыши.

Какую роль играет aria-roledescription в карусели?

Атрибут aria-roledescription [4] помогает предоставить более конкретное описание роли карусели. Это делает ее более понятной для пользователей скринридеров, сообщая, что это именно карусель. Вы можете использовать, например, "Карусель изображений" или "Карусель продуктов", чтобы дать контекст содержимому. Он зачитывается скринридером как есть, и вы должны перевести его на язык пользователя [5].

Следует ли использовать радиокнопки или обычные кнопки для точечной навигации в карусели?

Радиокнопки являются лучшим выбором для точечной навигации, так как они обеспечивают простую клавиатурную навигацию [18] и передают концепцию выбора определенного слайда [8]. Они также по умолчанию поддерживают клавиатурные взаимодействия, такие как СтрелкаВлево, СтрелкаВправо и Enter для выбора, что делает их более доступными, чем обычные кнопки.

Однако, если реализация с радиокнопками действительно не работает, вы можете использовать обычные кнопки. Убедитесь, что вы поместили их в список <ul> с элементами <li> [7] и что они фокусируемы и управляются с клавиатуры [18]. Каждая кнопка должна иметь aria-label, описывающий ее функцию, например, "Перейти к Слайду 1", "Перейти к Слайду 2" и т. д. [9].

Почему функция автоматической ротации карусели должна быть управляемой?

Автоматическая ротация должна управляться с помощью кнопки Пауза/Воспроизведение [15], чтобы вы могли остановить или запустить ротацию по желанию. Это необходимо для пользователей, которым требуется больше времени для взаимодействия с содержимым, и гарантирует, что ротация не мешает [14].

Как мне поступить с остановкой автоматической ротации при взаимодействии пользователя с каруселью?

Автоматическая ротация должна останавливаться, когда вы взаимодействуете с каруселью, фокусируя элемент или наводя мышь на содержимое. Это предотвращает неожиданную смену слайдов, пока вы заняты содержимым [14]. Ротация должна продолжаться только в том случае, если вы явно запустите ее снова с помощью кнопки Пауза/Воспроизведение.

Для чего используются aria-live и aria-atomic в каруселях?

Атрибут aria-live сообщает скринридерам, что они должны динамически объявлять изменения, например, при смене слайдов карусели [13]. С aria-live="polite" вы гарантируете, что изменение будет объявлено без прерывания вашей текущей задачи. Атрибут aria-atomic="true" гарантирует, что объявляется все обновление, а не только последнее изменение.

Следует ли объявлять смену слайдов во время автоматической ротации?

Нет, это не обязательно. Вам не нужно объявлять смену слайдов во время авторотации, так как это фоновый процесс, не требующий вашего внимания. Однако, если вы перемещаетесь вручную (например, с помощью кнопок или точек), изменение должно быть объявлено [13].

Как я могу гарантировать доступность навигационных кнопок?

Навигационные кнопки (например, "Назад" и "Далее") следует реализовать как элементы <button> с атрибутами aria-label, описывающими их функцию [9]. Это гарантирует, что они фокусируемы, управляются с клавиатуры (через Enter или Пробел) [18] и корректно объявляются скринридерами [10].

Почему скрытые слайды должны быть помечены aria-hidden="true"?

Скрытые слайды следует помечать aria-hidden="true", чтобы они не объявлялись скринридерами и не могли быть сфокусированы с клавиатуры [10]. Это предотвращает путаницу и гарантирует, что только активный слайд является интерактивным и объявляется.

Как справиться с переходами слайдов, чтобы избежать гонок состояний (Race Conditions)?

Чтобы избежать "гонок состояний" во время переходов (например, когда карусель пропускает слайд), вы должны отложить управление фокусом до завершения перехода. Это можно сделать с помощью setTimeout в JavaScript, чтобы убедиться, что фокус переходит на активный слайд только после завершения анимации [11].

Почему я должен реализовывать aria-posinset и aria-setsize на каждом слайде?

Использование aria-posinset и aria-setsize помогает сообщить позицию и общее количество слайдов в карусели [8]. Это улучшает навигацию для пользователей скринридеров. Например, "Слайд 1 из 5" позволяет пользователям узнать, сколько слайдов всего и какой из них сейчас виден.

Как я могу убедиться, что карусель семантически корректна?

Убедитесь, что ваша структура карусели использует семантические HTML-элементы, такие как <section> для контейнера [1], <ul> и <li> для слайдов [7] и <article> для содержимого в каждом слайде [1]. Используйте подходящие ARIA-атрибуты, такие как aria-roledescription [4], aria-labelledby [3] и aria-hidden, чтобы улучшить доступность.

Следует ли использовать display: none или inert для скрытых слайдов?

Рекомендуемый способ скрыть слайды — использовать inert и aria-hidden="true". Это удаляет слайд из Дерева Доступности [10], при этом анимации все еще возможны. Избегайте display: none для слайдов, которым нужна анимация, так как это не анимируется. Если анимация вам не нужна, display: none подходит для полного скрытия слайдов.

Однако будьте осторожны с атрибутом inert, так как он может не поддерживаться во всех браузерах. Если вам нужно поддерживать старые браузеры, вы можете использовать visibility: hidden вместе с aria-hidden="true", чтобы скрыть содержимое и удалить его из Дерева Доступности и клавиатурной навигации. Единственная проблема: visibility: hidden не удаляет слайд из DOM, что может привести к проблемам с производительностью, если вы скрываете много слайдов одновременно.

Что означает поддержка клавиш Home и End для точек карусели?

Поддерживая клавиши Home и End в точечной навигации, вы позволяете пользователям быстро переходить к первому или последнему слайду. Это улучшает навигацию для пользователей клавиатуры [18].

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

Что делать, если анимация карусели вызывает проблемы с объявлениями скринридера?

Убедитесь, что объявления скринридера не прерываются во время переходов слайдов. Чтобы избежать этого, отложите объявление до завершения перехода или используйте aria-live="polite", чтобы мягко объявлять изменения содержимого, не нарушая пользовательский опыт [13].

  1. W3C, «G115: Using semantic elements to mark up structure», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/general/G115
  2. W3C, «ARIA11: Using ARIA landmarks to identify regions of a page», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA11
  3. W3C, «ARIA13: Using aria-labelledby to name regions and landmarks», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA13
  4. W3C, «ARIA4: Using a WAI-ARIA role to expose the role of a user interface component», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA4
  5. W3C, «Success Criterion 3.1.2 Language of Parts», 2023, [Онлайн]. Доступно на: https://www.w3.org/TR/WCAG22/#language-of-parts
  6. W3C, «G141: Organizing a page using headings», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/general/G141
  7. W3C, «H48: Using ol, ul and dl for lists or groups of links», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/html/H48
  8. W3C, «Success Criterion 1.3.1 Info and Relationships», 2023, [Онлайн]. Доступно на: https://www.w3.org/TR/WCAG22/#info-and-relationships
  9. W3C, «ARIA6: Using aria-label to provide labels for objects», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA6
  10. W3C, «Success Criterion 4.1.2 Name, Role, Value», 2023, [Онлайн]. Доступно на: https://www.w3.org/TR/WCAG22/#name-role-value
  11. W3C, «Success Criterion 2.4.3 Focus Order», 2023, [Онлайн]. Доступно на: https://www.w3.org/TR/WCAG22/#focus-order
  12. W3C, «G59: Placing the interactive elements in an order that follows sequences and relationships within the content», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/general/G59
  13. W3C, «Success Criterion 4.1.3 Status Messages», 2023, [Онлайн]. Доступно на: https://www.w3.org/TR/WCAG22/#status-messages
  14. W3C, «Success Criterion 2.2.2 Pause, Stop, Hide», 2023, [Онлайн]. Доступно на: https://www.w3.org/TR/WCAG22/#pause-stop-hide
  15. W3C, «G4: Allowing the content to be paused and restarted from where it was paused», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/general/G4
  16. W3C, «H65: Using the title attribute to identify form controls when the label element cannot be used», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/html/H65
  17. W3C, «ARIA16: Using aria-labelledby to provide a name for user interface controls», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA16
  18. W3C, «Success Criterion 2.1.1 Keyboard», 2023, [Онлайн]. Доступно на: https://www.w3.org/TR/WCAG22/#keyboard
  19. W3C, «Success Criterion 2.4.7 Focus Visible», 2023, [Онлайн]. Доступно на: https://www.w3.org/TR/WCAG22/#focus-visible
  20. W3C, «Success Criterion 1.4.11 Non-text Contrast», 2023, [Онлайн]. Доступно на: https://www.w3.org/TR/WCAG22/#non-text-contrast
  21. W3C, «Success Criterion 2.5.5 Target Size (Enhanced)», 2023, [Онлайн]. Доступно на: https://www.w3.org/TR/WCAG22/#target-size-enhanced
  22. W3C, «F59: Failure of Success Criterion 4.1.2 due to using script to make div or span a user interface control in HTML without providing a role for the control», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/failures/F59
  23. W3C, «Success Criterion 1.1.1 Non-text Content», 2023, [Онлайн]. Доступно на: https://www.w3.org/TR/WCAG22/#non-text-content
  24. W3C, «Success Criterion 3.2.3 Consistent Navigation», 2023, [Онлайн]. Доступно на: https://www.w3.org/TR/WCAG22/#consistent-navigation
  25. W3C, «H71: Providing a description for groups of form controls using fieldset and legend elements», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/html/H71
  26. W3C, «H37: Using alt attributes on img elements», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/html/H37
  27. W3C, «ARIA22: Using role=status to present status messages», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA22
  28. W3C, «G73: Providing a long description in another location with a link to it that is immediately adjacent to the non-text content», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/general/G73
  29. W3C, «ARIA1: Using the aria-describedby property to provide a descriptive label for user interface controls», 2023, [Онлайн]. Доступно на: https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA1

Об авторе

Портрет Дмитрия Дугарева

С наилучшими пожеланиями,

Дмитрий Дугарев

Основатель Barrierenlos℠ и разработчик плагина Semanticality™. Имея степень магистра, более 8 лет опыта в веб-разработке и IT-комплаенса в компаниях «Большой четвёрки», банках и концернах и более 1 000 протестированных на доступность веб-страниц для более чем 50 клиентов, я помогаю веб-командам системно внедрять доступность — без многомесячных переделок.

Станьте сами разработчиком-профи EAA - всего за 4 дня!

Узнайте на нашем 4-дневном семинаре, как самостоятельно проводить сложные аудиты и создавать доступные компоненты. Получите индивидуальный учебный план, 1:1 стратегическую консультацию и сертификат.

Зарегистрироваться на воркшоп сейчас

На этой странице