Пример аудита доступности согласно WCAG 2.2 A и AA
Информация о статье

Автор: Дмитрий Дугарев
В этой статье я систематически проверил веб-сайт portfolio.barrierenlos.com/audit-demo на соответствие критериям WCAG 2.2 A и AA [1]. Проверка проводилась 06 апреля 2025 года. При этом использовались как автоматизированные инструменты (симулированная проверка с помощью расширения браузера WAVE, ручная инспекция кода), так и ручные тесты со скринридером и навигацией с клавиатуры.
Отчет структурирован так же, как WCAG 2.2 [1], с оценкой по каждому критерию. Для каждого невыполненного критерия WCAG 2.2 (A и AA) были подготовлены подробные объяснения с примерами кода и выведены соответствующие задачи (To-Dos). В конце отчета находится обзор всех задач, собранных в ходе аудита. Выполнение этих задач обеспечит доступный веб-сайт и соответствие Европейскому акту о доступности (ЕАА) [2].
Ниже подробно представлены результаты и рекомендации.
Доступен ли Ваш веб-сайт для восприятия всеми пользователями?
Воспринимаемость (Perceivable) — это первый из четырех основополагающих принципов доступности в интернете [3].
Он закладывает основу для того, чтобы все пользователи, независимо от их сенсорных способностей, имели доступ к Вашему контенту.
Независимо от того, есть ли у кого-то нарушения зрения, слуха или он использует специальные технологии для работы в интернете, соблюдение следующих руководств гарантирует, что никто не будет исключен.
Предоставьте текстовые альтернативы для всего, что не является текстом.
Не выполнено: Нетекстовое содержимое – WCAG 2.2, 1.1.1. (A)
- Предоставили ли Вы краткую текстовую альтернативу для всего простого нетекстового содержимого, которая выполняет ту же цель и передает ту же информацию?
- Предоставили ли Вы более подробное текстовое описание для сложного нетекстового содержимого, такого как диаграммы или инфографика? (Такого содержимого нет)
- Добавили ли Вы четкое и однозначное текстовое описание для всех элементов управления и полей ввода, объясняющее их функцию? (Рассматривается в 3.3.2 и 4.1.2, где оно не выполняется)
- Предоставили ли Вы подходящее краткое текстовое описание для медиафайлов или содержимого, основанного на времени? (Соответствующие медиафайлы, основанные на времени, отсутствуют)
- Предоставили ли Вы текстовое описание для CAPTCHA и предложили ли альтернативный метод? (CAPTCHA отсутствует)
- Было ли нетекстовое содержимое реализовано или отмечено таким образом, чтобы вспомогательные технологии игнорировали его, если оно не несет важной информации?
Многочисленные изображения на веб-сайте имеют альтернативные тексты. Это касается изображений почти во всех разделах: слайдер, функции, чередующиеся разделы.
Пример из слайдера:

В результате пользователи скринридеров теряют важную информацию или контекст становится неясным. Каждое изображение, несущее важную информацию (не чисто декоративное), требует описательного альтернативного текста [4], [5]. Чисто декоративные изображения должны иметь пустой атрибут alt="", чтобы скринридеры их пропускали [6], [7].
<img src="bild-2.jpg" alt="" width="..." height="..." />
Однако на этой демонстрационной странице все изображения, вероятно, чисто декоративны и не требуют описания. Они ничего не добавляют к содержанию и скорее перегрузят пользователя дополнительным контентом.
Задачи:
- Очистить альтернативные тексты для всех изображений.
- Проверить, действительно ли отдельные изображения являются чисто декоративными, и явно пометить их
alt="".
Предоставьте альтернативы для медиафайлов, основанных на времени.
На этом веб-сайте нет встроенных медиафайлов, основанных на времени (аудио или видео). Следовательно, все требования в этом разделе выполнены.
Выполнено: Только аудио и Только видео (Предварительно записанное) – WCAG 2.2, 1.2.1 (A)
- Предоставили ли Вы эквивалентную текстовую альтернативу для всего предварительно записанного аудиоконтента?
- Предоставили ли Вы эквивалентную текстовую альтернативу или аудиодорожку для всего предварительно записанного видеоконтента без звука?
Выполнено: Субтитры (Предварительно записанное) – WCAG 2.2, 1.2.2 (A)
- Предлагаете ли Вы субтитры для предварительно записанного аудиоконтента в синхронизированных медиафайлах?
Выполнено: Аудиодескрипция или медиа-альтернатива (Предварительно записанное) – WCAG 2.2, 1.2.3 (A)
- Предоставили ли Вы для предварительно записанного видеоконтента либо аудиодескрипцию, либо текстовую альтернативу?
Выполнено: Субтитры (В режиме реального времени) – WCAG 2.2, 1.2.4 (AA)
- Предлагаете ли Вы субтитры для аудиоконтента в режиме реального времени в синхронизированных медиафайлах?
Выполнено: Аудиодескрипция (Предварительно записанное) – WCAG 2.2, 1.2.5 (AA)
- Добавили ли Вы аудиодескрипцию для предварительно записанных видео в синхронизированных медиафайлах?
Создавайте гибкое содержимое без потери информации.
Ваш веб-сайт должен быть спроектирован таким образом, чтобы он адаптировался к потребностям пользователей. Это касается не только отображения на различных устройствах, но и работы с различными методами ввода.
Не выполнено: Информация и отношения – WCAG 2.2, 1.3.1 (A)
- Становятся ли информация и отношения программно распознаваемыми с помощью семантической структуры?
- Если используемая технология не поддерживает семантическую структуру, предлагаете ли Вы текстовые альтернативы или дополнительные пояснения? (HTML поддерживает семантику, она просто не используется)
Семантическая HTML-структура веб-сайта является фундаментально дефектной. Она почти исключительно использует общие элементы <div> и <span> вместо семантически корректных HTML-тегов, которые делают структуру и значение контента понятными для вспомогательных технологий (таких как скринридеры) и браузеров [8]. Это приводит к значительным барьерам.
Структура страницы и ориентиры (Landmarks)
Области страницы, такие как заголовок (Header), навигация, основной контент, отдельные разделы (Секции) и нижний колонтитул (Footer), не размечены предназначенными для этого элементами HTML5 (<header>, <nav>, <main>, <section>, <footer>) [9], [10]. Эти элементы определяют так называемые «регионы-ориентиры» (Landmark Regions), которые позволяют пользователям вспомогательных технологий быстро перемещаться между важными областями страницы.
Это необязательно, но Вы можете явно связать раздел с его заголовком с помощью aria-labelledby [11], введя туда id элемента заголовка. Таким образом, область помечается как «Ориентир» для пользователей, и они могли бы, например, быстро получить к ней доступ или быстро перейти от одного к другому через меню ротора скринридера.
Если это невозможно, просто убедитесь, что разделы размечены с помощью <h1...6> [12]. Затем пользователи могут быстро ориентироваться на странице, просматривая все заголовки в меню ротора.
- Код проблемного места
- Код, каким он должен быть
<body>
<div class="site-header"></div>
<div class="hero">...</div>
<div class="slider-section">...</div>
<div class="section">...</div>
<div class="section-alt">...</div>
<div class="site-footer">...</div>
</body>
<body>
<a href="#main-content" class="skip-link">Перейти к содержанию</a>
<header class="site-header"></header>
<main id="main-content">
<div class="hero">
<h1 id="hero-title">...</h1>
...
</div>
<section class="slider-section" aria-labelledby="slider-title">
<h2 id="slider-title">Актуальные моменты.</h2>
...
</section>
<section class="features-section" aria-labelledby="features-title">
<h2 id="features-title">...</h2>
...
</section>
<section class="alternating-section-1" aria-labelledby="alt1-title">
<h2 id="alt1-title">...</h2>
...
</section>
</main>
<footer class="site-footer"></footer>
</body>
При этом важно отметить, что первая секция не помечена как таковая, потому что заголовок в этой секции описывает всю страницу.
Задачи:
- Разметить структуру страницы с помощью корректных элементов-ориентиров HTML5:
<header>,<nav>,<main>,<section>,<footer>. - Дать элементу
<main>ID (id="main-content") в качестве цели для ссылки пропуска (Skip-Link). - Использовать элементы
<section>для группировки тематически связанных блоков содержимого и называть их заголовками иaria-labelledby.
Заголовки
Заголовки представлены визуально стилизованными элементами <div> (.hero-title, .section-title, .feature-title, .layout-title) вместо настоящих тегов заголовков (<h1> - <h6>) [12]. В результате теряется иерархическая структура документа, которая необходима пользователям скринридеров для навигации и понимания организации страницы [8], [13].
- Код проблемного места
- Код, каким он должен быть
<div class="hero-title">Unlock Your Potential...</div>
<div class="section-title">Why Choose CoursePro?</div>
<div class="feature-item">
<div class="feature-title">Expert Instructors</div>
...
</div>
<h1 class="hero-title">Unlock Your Potential...</h1>
<h2 class="section-title">Why Choose CoursePro?</h2>
<div class="feature-item">
<h3 class="feature-title">Expert Instructors</h3>
...
</div>
Задачи:
- Заменить все визуальные заголовки корректными тегами заголовков HTML (
<h1>до<h6>). - Убедиться, что иерархия заголовков логически корректна (только один
<h1>на страницу, не пропускать уровни).
Списки для групп
Группы связанных элементов, таких как навигационные пункты, функции в сетке, шаги в разделе «Как это работает» или записи FAQ, не размечены как семантические списки (<ul>, <ol>, <li>). Вместо этого часто используются контейнеры <div>. В результате вспомогательные технологии не распознают, что это группа связанных элементов и сколько элементов в группе [14].
- Код проблемного места
- Код, каким он должен быть
- Код проблемного места (Сетка функций)
- Код, каким он должен быть (Сетка функций — Базовая структура):
<div class="main-nav">
<div>Features</div>
<div>Pricing</div>
<div>Testimonials</div>
</div>
<nav aria-label="Основная навигация">
<ul class="main-nav">
<li><a href="#features">Features</a></li>
<li><a href="#pricing">Pricing</a></li>
<li><a href="#testimonials">Testimonials</a></li>
</ul>
</nav>
<div class="features-grid">
<div class="feature-item">...</div>
<div class="feature-item">...</div>
<div class="feature-item">...</div>
</div>
<ul class="features-grid">
<li class="feature-item">...</li>
<li class="feature-item">...</li>
<li class="feature-item">...</li>
</ul>
Задачи:
- Структурировать навигационные меню как неупорядоченные списки (
<ul>) с элементами списка (<li>), содержащими ссылки (<a>). - Разметить сетки функций, списки отзывов, списки FAQ и т. д. как
<ul>с элементами<li>(см. также пункт 4). - Разметить пошаговые инструкции («Как это работает») как упорядоченные списки (
<ol>) с элементами<li>(см. также пункт 4).
Карточки и статьи (<article>)
Блоки содержимого, оформленные как карточки (например, отдельные функции, шаги в разделе «Как это работает», отзывы), часто представляют собой самодостаточные информационные единицы. Они должны быть не только сгруппированы в список (<ul>/<ol> -> <li>), но и содержимое каждой отдельной карточки должно быть дополнительно размечено элементом <article>.
Это дало бы пользователю скринридера необходимый контекст, например, сообщая ему напрямую, что список содержит два элемента.
Там видно, что пользователи сразу информируются о том, что это список из четырех элементов (карточек). Когда пользователи выбирают отдельный элемент, в конце сообщается, на какой позиции находится этот элемент в списке и сколько всего элементов.
Элемент <article> представляет собой полную или самодостаточную композицию в документе, которую в принципе можно распространять или повторно использовать независимо (например, сообщение на форуме, запись в блоге, продукт на странице магазина или описание функции).
- Код проблемного места (Сетка функций, продолжение)
- Код, каким он должен быть (Сетка функций — Базовая структура)
<div class="features-grid">
<div class="feature-item">
<div class="feature-title">Expert Instructors</div>
<div>Learn from the best...</div>
<img src="..." />
</div>
</div>
<ul class="features-grid">
<li class="feature-item">
<article aria-labelledby="feature1-title">
<img
src="https://source.unsplash.com/random/100x100/?lightbulb,idea"
alt="Лампочка как символ экспертных знаний"
/>
<h3 id="feature1-title" class="feature-title">
Expert Instructors
</h3>
<div>
Learn from the best in the industry. Our instructors are vetted
professionals.
</div>
</article>
</li>
<li class="feature-item">
<article aria-labelledby="feature2-title">
<img
src="https://source.unsplash.com/random/100x100/?books,laptop"
alt="Книги и ноутбук как символ гибкого обучения"
/>
<h3 id="feature2-title" class="feature-title">
Flexible Learning
</h3>
<div>
Access courses anytime, anywhere, on any device. Learn at your own
pace.
</div>
</article>
</li>
</ul>
Задачи:
- Структурировать разделы с макетом карточек (Функции, «Как это работает», возможно, Отзывы) как списки (
<ul>или<ol>). - Каждый отдельный карточку (например,
.feature-item,.step-item) заключить в элемент<li>. - Все содержимое внутри каждой карточки обернуть элементом
<article>. - Убедиться, что каждый
<article>содержит подходящий заголовок (например,<h3>,<h4>).
Интерактивные элементы (FAQ)
Интерактивные элементы, которые вызывают действия, такие как раскрытие ответов FAQ, реализованы как неинтерактивные элементы <div>. Они по умолчанию не фокусируются или не активируются с помощью клавиатуры и не имеют подходящей семантической роли (например, «Кнопка») или информации о состоянии (например, «раскрыто»/«свернуто») [15].
- Код проблемного места
- Код, каким он должен быть
<div class="faq-item">
<div class="faq-question">What payment methods...?</div>
<div class="faq-answer" style="display: none;">
...
</div>
</div>
<ul class="faq-list">
<li class="faq-item">
<h3>
<button
class="faq-question"
aria-expanded="false"
aria-controls="faq1-answer"
id="faq1-question"
>
What payment methods do you accept?
</button>
</h3>
<div
id="faq1-answer"
class="faq-answer"
role="region"
aria-labelledby="faq1-question"
hidden
>
We accept all major credit cards and PayPal.
</div>
</li>
<li class="faq-item">
<h3>
<button
class="faq-question"
aria-expanded="false"
aria-controls="faq2-answer"
id="faq2-question"
>
Can I get a refund if I'm not satisfied?
</button>
</h3>
<div
id="faq2-answer"
class="faq-answer"
role="region"
aria-labelledby="faq2-question"
hidden
>
Yes, we offer a 30-day money-back guarantee...
</div>
</li>
</ul>
Задачи:
- Реализовать вопросы FAQ как нативные элементы
<button>, желательно внутри подходящего заголовка (h3,h4...). - Структурировать всю секцию FAQ как список (
<ul>/<li>). - Для аккордеона FAQ добавить необходимые ARIA-атрибуты (
aria-expanded,aria-controls) и правильно управлять их состоянием с помощью JavaScript. - Контейнерам ответов присвоить подходящую роль (
role="region") и связь с вопросом (aria-labelledbyс ID кнопки) и скрывать их по умолчанию (например, с помощью атрибутаhidden).
Связи форм (Метки/Labels)
Полям ввода (<input>, <textarea>) в контактной форме не хватает связанных элементов <label>. В результате связь между видимой надписью (которая находится только в placeholder) и полем ввода не определена программно [16]. Скринридеры не могут правильно назвать поле. (Подробное исправление см. SC 3.3.2 Метки или инструкции).
- Код проблемного места
- Код, каким он должен быть
<form class="contact-form">
<input type="text" placeholder="Your Name" />
<input type="email" placeholder="Your Email Address" />
<textarea placeholder="Your Message"></textarea>
<button type="submit">Send Message</button>
</form>
<form class="contact-form">
<label for="contact-name">Your Name</label>
<input
type="text"
id="contact-name"
name="contact-name"
placeholder="Your Name"
autocomplete="name"
/>
<label for="contact-email">Your Email Address</label>
<input
type="email"
id="contact-email"
name="contact-email"
placeholder="Your Email Address"
autocomplete="email"
/>
<label for="contact-message">Your Message</label>
<textarea
id="contact-message"
name="contact-message"
placeholder="Your Message"
autocomplete="off"
></textarea>
<button type="submit">Send Message</button>
</form>
Задачи:
- Добавить явные элементы
<label>и правильно связать их с полями ввода черезfor/id. - Предоставить элементам
<input>атрибутautocomplete, чтобы обеспечить автоматическое заполнение формы.
Выполнено: Осмысленная последовательность – WCAG 2.2, 1.3.2 (A)
- Можно ли программно определить порядок содержимого, и сохраняется ли он осмысленно? (Порядок DOM, по-видимому, соответствует визуальному порядку)[17]
Выполнено: Сенсорные характеристики – WCAG 2.2, 1.3.3 (A)
- При использовании инструкций Вы не полагаетесь исключительно на сенсорные характеристики (цвет, форму, размер и т. д.)? [18]
Выполнено: Ориентация – WCAG 2.2, 1.3.4 (AA)
- Можно ли использовать страницу как в портретной, так и в ландшафтной ориентации, без потери функциональности или содержимого? (Ограничений не обнаружено) [19]
Не выполнено: Идентификация цели ввода – WCAG 2.2, 1.3.5 (AA)
- Помечены ли все поля, запрашивающие пользовательские данные (имя, адрес, электронная почта и т. д.), программно как таковые (например, Autocomplete)?
Поля ввода в контактной форме (Имя, Электронная почта, Сообщение) не имеют атрибутов autocomplete. Это затрудняет эффективное заполнение формы пользователям, которые зависят от функций автозаполнения браузера или вспомогательных технологий [20].
- Код проблемного места
- Код, каким он должен быть
<input type="email" placeholder="Your Email Address" />
<label for="email">Your Email Address</label>
<input
type="email"
id="email"
name="email"
placeholder="Your Email Address"
autocomplete="email"
/>
<label for="name">Your Name</label>
<input
type="text"
id="name"
name="name"
placeholder="Your Name"
autocomplete="name"
/>
Задачи:
- Добавить подходящие атрибуты
autocompleteдля полей Имя (autocomplete="name") и Электронная почта (autocomplete="email") в контактной форме.
Сделайте контент понятным и легко различимым.
Читаемость и различимость контента имеют решающее значение для доступности. Убедитесь, что тексты легко читаются, цвета контрастны, а размеры шрифтов достаточно велики. Элементы управления также должны быть четко различимы и легко отличимы друг от друга. Особенно важно, чтобы цвета не служили единственным источником информации, так как они не воспринимаются многими пользователями.
Выполнено: Использование цвета – WCAG 2.2, 1.4.1 (A)
- Используете ли Вы цвет не исключительно для передачи информации (например, состояний)? [21]
- Если цвет используется в изображениях, интегрировали ли Вы альтернативные представления (например, узоры, подписи)?
Выполнено: Управление аудио – WCAG 2.2, 1.4.2 (A)
- Воспроизводятся ли аудиосодержимое не автоматически дольше 3 секунд, или Вы предлагаете кнопку остановки/паузы? (Аудиосодержимое отсутствует) [22]
Не выполнено: Контраст (Минимум) – WCAG 2.2, 1.4.3 (AA)
- Имеет ли более крупный текст (например, от 18 pt или 14 pt жирным) контраст не менее 3:1? Имеет ли текст нормального размера (менее 18 pt и менее 14 pt жирным) контраст не менее 4,5:1?
Несколько текстовых элементов на странице не соответствуют минимальным требованиям к контрасту согласно WCAG AA [23], [24]:
-
Текст-заполнитель в формах: Текст-заполнитель (
#999) на белом фоне (#ffffff) имеет коэффициент контрастности всего 2.85:1. Это слишком низко, требуется 4,5:1.
-
Текст кнопки:
- Зеленая кнопка (фон
#28a745, текст#fff): Контраст 3.98:1 (слишком низко для обычного текста, требуется 4,5:1).
- Зеленая кнопка (фон
Задачи:
- Затемнить цвет текста-заполнителя или убедиться, что поля всегда имеют видимую метку
<label>. - Изменить фоновый цвет или цвет текста кнопок (зеленый), чтобы контраст составлял не менее 4.5:1 (поскольку текст имеет нормальный размер).
Выполнено: Масштабируемость текста – WCAG 2.2, 1.4.4 (AA)
- Может ли Ваш текст быть увеличен до 200 % без потери содержимого или непригодности к использованию? (Стандартное масштабирование браузера работает) [25]
Выполнено: Изображения текста – WCAG 2.2, 1.4.5 (AA)
- Избегаете ли Вы изображений текста, если того же эффекта можно достичь с помощью настоящего текста?
Выполнено: Перекомпоновка (Reflow) – WCAG 2.2, 1.4.10 (AA)
- Остается ли все содержимое пригодным для использования без горизонтальной прокрутки и без потери информации при ширине до 320 CSS-пикселей?
К сожалению, горизонтальная прокрутка есть:

Это происходит потому, что контейнеры в секциях с изображением слева имеют margin: 0 auto; и одновременно width: 90%. Одно из этих свойств должно быть удалено на мобильных устройствах [26], [27].
Задачи:
- Удалить
width: 90%илиmargin: 0 auto;для класса.containerна мобильных устройствах.
Не выполнено: Контраст нетекстового содержимого – WCAG 2.2, 1.4.11 (AA)
- Имеют ли элементы управления (кнопки, рамки фокуса и т. д.) контраст не менее 3:1 по отношению к фону?
- Содержат ли графические элементы важные области, которые имеют контраст не менее 3:1? (Нет сложных графиков, понимание которых зависит от контраста)
Несколько элементов управления на странице не соответствуют требованиям к контрасту нетекстового содержимого согласно WCAG AA [28], [29]:
-
Границы полей формы: Границы полей ввода (
#ccc) на белом фоне (#ffffff) имеют коэффициент контрастности всего 1.61:1. Это слишком низко для распознавания компонента.
-
Индикаторы фокуса: Отсутствуют видимые индикаторы фокуса для интерактивных элементов (см. 2.4.7). Таким образом, отсутствует и необходимый контраст для самого индикатора фокуса.

Задачи:
- Затемнить цвет границ полей ввода, чтобы достичь контраста не менее 3:1 (например,
#767676). - Реализовать видимые индикаторы фокуса с достаточным контрастом (см. 2.4.7).
Выполнено: Интервалы текста – WCAG 2.2, 1.4.12 (AA)
- Остается ли Ваша страница полностью пригодной для использования, если увеличиваются интервалы между строками и абзацами, а также между словами и символами? (Не обнаружено техник, препятствующих этому) [30]
Выполнено: Содержимое при наведении или фокусе – WCAG 2.2, 1.4.13 (AA)
- Остается ли дополнительно отображаемое содержимое (например, всплывающие подсказки) видимым, пока Вы его не закроете или не снимете фокус? (Такого содержимого нет)
Доступен ли Ваш веб-сайт для управления всеми пользователями?
Второй краеугольный камень доступности — это управляемость (Operable) [3].
Этот аспект гарантирует, что все пользователи — независимо от их физических возможностей или используемой ими технологии — могут легко перемещаться по Вашему веб-сайту и использовать все функции.
Сделайте все функции доступными с помощью клавиатуры.
Не выполнено: Клавиатура – WCAG 2.2, 2.1.1 (A)
- Доступна ли вся функциональность Вашего веб-сайта с помощью клавиатуры, без определенных временных ограничений?
Несколько центральных функций и интерактивных элементов веб-сайта недоступны с помощью клавиатуры [31]. Это исключает пользователей, которые не могут использовать мышь или полагаются на навигацию с клавиатуры (например, пользователи с нарушениями моторики или пользователи скринридеров).
Навигация недоступна с помощью клавиатуры
Элементы основной навигации реализованы как элементы <div>. Элементы <div> по умолчанию не являются интерактивными и не получают фокус клавиатуры. К ним нельзя перейти с помощью клавиши Tab и нельзя активировать с помощью Enter или пробела [31].
Только нативные интерактивные элементы, такие как ссылки (<a> с href) и кнопки (<button>, <input type="button"> и т. д.) или элементы с явным tabindex="0" [32], по умолчанию доступны для фокусировки и управления с клавиатуры. Использование <div> для навигации предотвращает это.
- Код проблемного места:
- Код, каким он должен быть:
<div class="site-header">
<div class="container nav-container">
<div class="logo">CoursePro</div>
<div class="main-nav">
<div>Features</div>
<div>Pricing</div>
<div>Testimonials</div>
<div>Contact</div>
<div>FAQ</div>
</div>
</div>
</div>
<header class="site-header">
<div class="container nav-container">
<div class="logo">CoursePro</div>
<nav aria-label="Основная навигация">
<ul class="main-nav">
<li><a href="#features">Features</a></li>
<li><a href="#pricing">Pricing</a></li>
<li><a href="#testimonials">Testimonials</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="#faq">FAQ</a></li>
</ul>
</nav>
</div>
</header>
Задачи:
- Заменить элементы
<div>навигации настоящими элементами<a>со значимыми атрибутамиhref. - Построить структуру навигации семантически корректно как список (
<ul>/<li>) внутри элемента<nav>[14], [33].
FAQ недоступен с помощью клавиатуры
Вопросы в разделе FAQ, которые используются для развертывания/свертывания ответов, также реализованы как элементы <div> (<div class="faq-question">). Как и в случае с навигацией, они не фокусируются с помощью клавиатуры и не активируются [31].
Для такой функции развертывания (аккордеон) элемент <button> является семантически корректным и доступным выбором [15]. Кнопки фокусируются с помощью клавиатуры и могут быть запущены с помощью Enter/пробела для начала связанного действия (здесь: развертывание/свертывание содержимого с помощью JavaScript).
- Код проблемного места:
- Код, каким он должен быть:
<div class="faq-item">
<div class="faq-question">What payment methods do you accept?</div>
<div class="faq-answer" style="display: none;">
...
</div>
</div>
<ul class="faq-list">
<li class="faq-item">
<h3>
<button
class="faq-question"
aria-expanded="false"
aria-controls="faq1-answer"
id="faq1-question"
>
What payment methods do you accept?
</button>
</h3>
<div
id="faq1-answer"
class="faq-answer"
role="region"
aria-labelledby="faq1-question"
hidden
>
We accept all major credit cards and PayPal.
</div>
</li>
</ul>
Задачи:
- Заменить элементы
<div>для вопросов FAQ (.faq-question) элементами<button>. - Убедиться, что эти кнопки правильно управляют состоянием (
aria-expanded) и видимостью ответов (атрибутhidden) с помощью JavaScript [15].
Отсутствие управления слайдером/маркизом с клавиатуры
Автоматически прокручивающийся слайдер изображений и текстовый маркиз не предлагают никаких элементов управления. Следовательно, нет и доступных с клавиатуры элементов управления для контроля этого динамического содержимого (например, остановки, продолжения, ручного перелистывания) [31], [34].
Каждая функциональность, которая запускается с помощью мыши или автоматически, также должна иметь эквивалентное управление с клавиатуры. Для слайдеров и маркизов это, как правило, означает кнопки для паузы/запуска анимации и, при необходимости, для ручной навигации. Эти кнопки должны быть реализованы как <button>, чтобы обеспечить управляемость с клавиатуры.
- Код проблемного места
- Код, каким он должен быть
<div class="slider-section">
<div class="slides-wrapper">...</div>
</div>
<div class="marquee-section">
<div class="marquee-content">...</div>
</div>
<section
class="slider-section"
aria-roledescription="carousel"
aria-labelledby="slider-title"
>
<h2 id="slider-title" class="visually-hidden">Актуальные моменты</h2>
<div class="slider-controls">
<button class="slider-control pause" aria-label="Остановить анимацию">
Пауза
</button>
<button class="slider-control prev" aria-label="Предыдущий слайд">‹</button>
<button class="slider-control next" aria-label="Следующий слайд">›</button>
</div>
<div class="slides-wrapper" aria-live="off">...</div>
</section>
<section class="marquee-section" aria-labelledby="marquee-title">
<h2 id="marquee-title" class="visually-hidden">Бегущая строка</h2>
<button class="marquee-control pause" aria-label="Остановить бегущую строку">
Пауза
</button>
<div class="marquee-content-wrapper" style="overflow:hidden;">
<div class="marquee-content">...</div>
</div>
</section>
Задачи:
- Добавить явные элементы управления (как минимум Воспроизведение/Пауза) для слайдера и маркиза. Реализовать их как элементы
<button>. - Убедиться, что эти кнопки доступны с клавиатуры и их функция (остановка/запуск анимации) может быть вызвана с помощью Enter/пробела (через слушатель событий JavaScript).
- Для слайдера дополнительно реализовать кнопки Вперед/Назад (
<button>) для обеспечения ручной навигации с клавиатуры.
Выполнено: Отсутствие ловушки клавиатуры – WCAG 2.2, 2.1.2 (A)
- Существует ли ловушка клавиатуры? Можете ли Вы в любой момент переместить фокус дальше или выйти из него? (Ловушка не обнаружена) [37]
Выполнено: Клавишные комбинации на основе символов – WCAG 2.2, 2.1.4 (A)
- Если Вы используете клавишные комбинации на основе символов (букв/цифр), можно ли их деактивировать или переназначить, или они работают только, когда элемент находится в фокусе? (Такие комбинации не реализованы)
Предоставьте пользователям достаточно времени для чтения и использования содержимого.
Выполнено: Настраиваемое ограничение по времени – WCAG 2.2, 2.2.1 (A)
- Можете ли Вы отключить или продлить тайм-ауты сеанса (минимум в 10 раз)? (Тайм-ауты не реализованы) [38]
- Управляет ли тайм-аутом скрипт? Можете ли Вы его отключить или продлить? (Тайм-ауты не реализованы)
- Есть ли у Вас функция Паузы или Остановки при ограниченном по времени чтении (например, бегущий текст)? (Проблема с маркизом в 2.2.2)
Не выполнено: Приостановка, остановка, скрытие – WCAG 2.2, 2.2.2 (A)
- Можете ли Вы остановить, приостановить или скрыть движущееся, мигающее или автоматически обновляемое содержимое?
Несколько автоматически воспроизводимых элементов на странице не предоставляют возможности остановить или приостановить движение [35]. Это касается, в частности:
- Слайдер: Слайдер изображений в верхней части страницы воспроизводится автоматически и непрерывно, без возможности для пользователя остановить его, приостановить или вручную переключить слайды [34].
- Маркиз (Marquee): Маркиз с текстом («Trusted By Thousands...») также воспроизводится автоматически и бесконечно с помощью CSS-анимации, без возможности управления.
Этот автоматически движущийся контент может быть очень навязчивым или даже вредным для пользователей с когнитивными нарушениями, нарушениями внимания или вестибулярными расстройствами.
Задачи:
- Добавить элементы управления для слайдера (например, кнопка Пауза/Воспроизведение, стрелки Вперед/Назад, индикаторы слайдов), которые также доступны с клавиатуры.
- Для маркиза также предложить функцию Пауза/Воспроизведение или остановить анимацию по умолчанию и запускать только по действию пользователя.
- Альтернативно или дополнительно: Уважать CSS-медиазапрос
prefers-reduced-motionи отключать анимации для пользователей, которые настроили это в своей системе.
Избегайте контента, который может вызвать приступы или физические реакции.
Выполнено: Три вспышки или ниже порога – WCAG 2.2, 2.3.1 (A)
- Содержит ли Ваш веб-сайт мигающий или мерцающий контент, который может вызвать приступы? [39]
Сделайте Ваш веб-сайт навигационным для всех пользователей.
Существует не только мышь и сенсорный экран. Многие пользователи используют клавиатуры, скринридеры или другие вспомогательные средства для перемещения по Вашему веб-сайту.
Не выполнено: Пропуск блоков – WCAG 2.2, 2.4.1 (A)
- Можете ли Вы пропускать повторяющееся содержимое, например, с помощью ссылки «Перейти к содержанию»?
Веб-сайту не хватает механизма для пропуска повторяющихся блоков, таких как основная навигация. Пользователям клавиатуры приходится проходить табуляцией через все элементы навигации при каждом открытии страницы, прежде чем они доберутся до основного содержимого [40].

Первая скрытая область навигации служит «Ссылки пропуска» (Skip Link), чтобы позволить пользователям — особенно тем, кто использует вспомогательные технологии — напрямую перейти к основному содержимому. Использование aria-label четко сообщает о цели ссылки.
- HTML
- CSS
<nav aria-label="Область перехода">
<ul class="stmc-links__wrapper">
<li>
<a
href="#skip-link-target"
title="Перейти к основному содержанию"
class="stmc-link"
>Перейти к основному содержанию
</a>
</li>
</ul>
</nav>
.stmc-link,
.stmc-link:visited {
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, -100%);
z-index: -1;
opacity: 0;
&:focus {
top: 0;
opacity: 1;
transform: translate(-50%, 0);
z-index: 99999999;
}
}
.stmc-links__wrapper {
position: absolute;
z-index: -1;
inset: 0;
opacity: 0;
&:focus-within {
opacity: 1;
z-index: 9999999;
}
}
В качестве альтернативы Вы можете просто разместить ссылку как первый элемент на странице [40]:
- HTML
<a
href="#skip-link-target"
title="Перейти к основному содержанию"
class="stmc-link"
>
Перейти к основному содержанию
</a>
Задачи:
- Убедиться, что ссылка также видна и легко распознаваема при использовании клавиатуры.
- Проверить, правильно ли определена целевая область перехода (
id="skip-link-target") и примыкает ли она непосредственно к основному содержимому.
Выполнено: Заголовок страницы – WCAG 2.2, 2.4.2 (A)
- Имеет ли каждая страница содержательный заголовок, который передает тему или цель? (Тег
<title>"Inaccessible Course Platform - Demo v2" присутствует) [41]
Выполнено: Порядок фокуса – WCAG 2.2, 2.4.3 (A)
- Является ли порядок фокуса логичным, чтобы не нарушать смысл и управляемость? (Внутри фокусируемых элементов порядок, по-видимому, логичен) [42]
Не выполнено: Цель ссылки (в контексте) – WCAG 2.2, 2.4.4 (A)
- Является ли цель каждой ссылки однозначной через видимый текст ссылки или программно определенный контекст?
Цель элементов, предназначенных для навигации, часто не может быть программно определена или скрывается из-за использования семантически неверных элементов. Это мешает пользователям вспомогательных технологий правильно идентифицировать варианты навигации и понять, куда ведет клик [43].
Цель навигации не определена программно (Divs вместо ссылок)
В основной навигации и ссылках в нижнем колонтитуле используются элементы <div> или <span> вместо настоящих ссылок (<a>). Хотя видимый текст (например, "Features", "Privacy Policy") может быть понятен зрячим пользователям, этим элементам не хватает семантической роли ссылки. Вспомогательные технологии не распознают их как элементы навигации, и цель («перейти на другую страницу/раздел») программно не очевидна.


- Код проблемного места (Навигация)
- Код проблемного места (Футер)
<div class="main-nav">
<div>Features</div>
<div>Pricing</div>
</div>
```html
<div class="footer-links">
<span>Privacy Policy</span> <span>Terms of Service</span>
</div>
Только правильно реализованный элемент <a> с атрибутом href однозначно сигнализирует о роли и цели гиперссылки [44]. Сам текст ссылки должен затем описывать цель или функцию ссылки [43].
- Код, каким он должен быть (Навигация)
- Код, каким он должен быть (Футер)
<nav aria-label="Основная навигация">
<ul class="main-nav">
<li>
<a href="#features">Features</a>
</li>
<li>
<a href="#pricing">Pricing</a>
</li>
<li>
<a href="#testimonials">Testimonials</a>
</li>
</ul>
</nav>
<nav aria-label="Правовые уведомления и Сервис">
<ul class="footer-links">
<li>
<a href="/privacy-policy">Privacy Policy</a>
</li>
<li>
<a href="/terms-of-service">Terms of Service</a>
</li>
</ul>
</nav>
Задачи:
- Все элементы, предназначенные для навигации (навигация в заголовке, ссылки в нижнем колонтитуле), реализовать как корректные элементы
<a>с действительным атрибутомhrefи содержательным текстом ссылки. - Убедиться, что эти ссылки встроены в семантически корректную структуру (например,
nav > ul > li > a).
Кнопки используются для чистой навигации (Кнопки вместо ссылок)
В нескольких местах используются элементы <button> для призывов к действию (CTAs), основная функция которых, однако, заключается в навигации на другую страницу или раздел (например, "Get Started Today", "Explore Courses").

Семантически <button> предназначен для действий внутри текущей страницы (отправка формы, изменение состояния, открытие диалога). Для чистой навигации корректным элементом является ссылка (<a>) [44]. Использование кнопки передает вспомогательным технологиям ложное ожидание относительно выполняемого действия.
Хотя текст кнопки может быть ясен, role="button" сигнализирует о действии, а не о навигации. Это может сбивать с толку. Если клик ведет пользователя к другому URL или якорю на странице, следует использовать элемент <a>, который соответствующим образом стилизован, чтобы выглядеть как кнопка.
- Код проблемного места:
- Код, каким он должен быть:
<button class="cta-button">Get Started Today</button>
<button class="section-cta-button">Explore Courses</button>
<a href="/signup" class="cta-button button-like">
Get Started Today
</a>
<a href="/courses" class="section-cta-button button-like">
Explore Courses
</a>
Задачи:
- Проверить все элементы
<button>на веб-сайте. - Кнопки, основная функция которых — навигация на другой URL или якорь, заменить элементами
<a>с соответствующим атрибутомhref. - Убедиться, что текст ссылки четко описывает цель или назначение ссылки.
- При необходимости перенести визуальное оформление кнопок с помощью CSS на элементы
<a>.
Не выполнено: Несколько путей – WCAG 2.2, 2.4.5 (AA)
- Предлагаете ли Вы несколько путей навигации (например, поиск, карта сайта, меню) для нахождения страниц?
Веб-сайт предлагает только одну основную навигацию (в заголовке, которая к тому же недоступна) и рудиментарный набор ссылок в нижнем колонтитуле (который также недоступен). Отсутствует карта сайта и функция поиска. Таким образом, отсутствуют альтернативные способы нахождения содержимого, особенно если основная навигация не может быть использована [45], [46], [47].
Задачи:
- Предоставить как минимум один дополнительный способ навигации. Варианты:
- Создать и разместить ссылку на страницу карты сайта.
- Реализовать функцию поиска.
- Убедиться, что основная навигация и навигация в нижнем колонтитуле последовательно ссылаются на все важные страницы.
Не выполнено: Заголовки и метки – WCAG 2.2, 2.4.6 (AA)
- Являются ли заголовки и метки содержательными и описывают ли они тему или цель?
Несколько заголовков и меток форм на странице реализованы семантически некорректно, что затрудняет навигацию и понимание для пользователей вспомогательных технологий [48], [49]. В частности, это касается:
- Заголовки: Как описано в 1.3.1, не используются настоящие теги заголовков (
<h1><h6>). Стилизованные<div>не выполняют функцию программной структуризации страницы [12]. - Метки: Как описано в 3.3.2, полям формы в контактной области не хватает явных элементов
<label>. Заполнители (Placeholder) не являются достаточными метками [16].
Задачи:
- Использовать настоящие, иерархически корректные заголовки (
<h1><h6>) для всех разделов и подразделов. - Предоставить явные, правильно связанные элементы
<label>для всех полей формы.
Не выполнено: Фокус виден – WCAG 2.2, 2.4.7 (AA)
- Виден ли фокус клавиатуры, когда Вы перемещаетесь по странице?
В CSS страницы отсутствуют явные стили :focus-visible для всех интерактивных элементов [50]. Это касается:
- Элементов
<div>в навигации (которые все равно не фокусируются). - Элементов
<button>(CTA Hero, Отправка формы, CTA разделов). - Полей
<input>и<textarea>в контактной форме. - Элементов
<div>для вопросов FAQ (которые также не фокусируются).
Без видимого индикатора фокуса пользователи клавиатуры не знают, какой элемент активен в данный момент, что чрезвычайно затрудняет или делает невозможным использование [50].
Задачи:
- Определить в CSS хорошо видимые стили
:focusдля всех интерактивных элементов (ссылок, кнопок, полей форм и т. д.). Индикатор фокуса должен четко выделяться на фоне и на самом элементе (см. также 1.4.11 Контраст нетекстового содержимого). Простогоoutlineчасто достаточно, например:
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
a:focus-visible,
[tabindex='0']:focus-visible {
outline: 2px solid blue; /* Пример */
outline-offset: 2px;
}
Выполнено: Фокус не скрыт (Минимум) – WCAG 2.2, 2.4.11 (AA)
- Не скрывается ли индикатор фокуса другими элементами, когда элемент получает фокус? (Нет закрепленных (sticky) заголовков/нижних колонтитулов или немодальных диалогов, которые могли бы скрыть фокус)
Сделайте Ваш веб-сайт доступным для всех методов ввода.
Выполнено: Жесты указателя – WCAG 2.2, 2.5.1 (A)
- Доступны ли все жесты несколькими пальцами или жесты по траектории (например, свайп, pinch-to-zoom) также просто с помощью одного указателя? (Такие жесты не требуются)
Выполнено: Отмена действия указателя – WCAG 2.2, 2.5.2 (A)
- Завершается ли действие только при поднятии указателя (MouseUp / TouchEnd) или есть опция Отменить/Отменить? (Стандартное поведение кнопок/полей ввода) [51]
Не выполнено: Метка в имени – WCAG 2.2, 2.5.3 (A)
- Совпадает ли видимый текст в метке с доступным именем?
Поскольку поля не имеют видимых элементов <label>, этот критерий не может быть выполнен. Доступное имя (которое было бы предоставлено меткой) отсутствует [16], [52]. Заполнители (Placeholder) не считаются метками.
Задачи:
- Добавить видимые элементы
<label>для всех полей формы (см. 3.3.2). Убедиться, что текст в метке четко описывает назначение поля.
Выполнено: Активация движением – WCAG 2.2, 2.5.4 (A)
- Могут ли движения устройства (например, встряхивание) быть также выполнены с помощью элемента управления и отключаете ли Вы нежелательные триггеры? (Функции, активируемые движением, отсутствуют) [53]
Выполнено: Жесты перетаскивания – WCAG 2.2, 2.5.7 (AA)
- Может ли функция, требующая перетаскивания (Drag & Drop), быть выполнена также без перетаскивания? (Drag & Drop отсутствует)
Выполнено: Размер цели (Минимум) – WCAG 2.2, 2.5.8 (AA)
- Все ли кликабельные/сенсорные области имеют размер не менее 24x24 CSS-пикселя или соответственно хорошо разделены? (Визуально кнопки и ссылки (если бы они были ссылками) кажутся достаточно большими или достаточно удаленными друг от друга)
Понятен ли Ваш веб-сайт для всех пользователей?
Третий краеугольный камень доступности — это понятность (Understandable) [3].
Этот аспект гарантирует, что все пользователи могут понять содержимое и управление веб-сайтом. Сюда входят четкий язык, простая навигация и понятные взаимодействия. Обратите особое внимание на то, чтобы скринридеры правильно произносили язык и управление было логичным.
Сделайте Ваш веб-сайт читабельным для всех пользователей.
Выполнено: Язык страницы – WCAG 2.2, 3.1.1 (A)
- Правильно ли размечен стандартный язык страницы (например,
lang="de")? (lang="en"установлен в HTML, что соответствует языку содержимого) [54]
Выполнено: Язык частей – WCAG 2.2, 3.1.2 (AA)
- Обозначаете ли Вы смену языка в тексте (например, цитаты, иностранные слова, отзывы клиентов и т. д.) атрибутами
lang? (Нет очевидных смен языка в демо-контенте) [55]
Сделайте Ваш веб-сайт предсказуемым для всех пользователей.
Выполнено: При фокусе – WCAG 2.2, 3.2.1 (A)
- Не меняется ли контекст автоматически, как только элемент получает фокус? [56]
Выполнено: При вводе – WCAG 2.2, 3.2.2 (A)
- Не меняется ли контекст автоматически, как только значение в элементе формы изменяется? [57]
Выполнено: Согласованная навигация – WCAG 2.2, 3.2.3 (AA)
- Повторяющиеся на нескольких страницах элементы навигации всегда расположены в одинаковом порядке? (Поскольку это только одна страница, это тривиально выполнено) [58]
Выполнено: Согласованная идентификация – WCAG 2.2, 3.2.4 (AA)
- Согласованно ли обозначены и помечены одинаково функционирующие элементы (например, одинаковые иконки, цвета)? (Кнопки имеют согласованный стиль) [59]
Не выполнено: Согласованная помощь – WCAG 2.2, 3.2.6 (A)
- Предлагаются ли функции помощи (Контакт, FAQ, Чат и т. д.) на всех страницах в одном и том же месте?
Веб-сайт предлагает раздел FAQ и раздел Контакты, но отсутствует согласованный, легко находимый механизм помощи, который был бы доступен на каждой (гипотетической) странице (например, всегда присутствующая ссылка «Помощь» в заголовке или нижнем колонтитуле). Кроме того, ссылки на FAQ и Контакты в заголовке недоступны (см. 2.1.1, 1.3.1).
Задачи:
- Предоставить согласованный механизм помощи на всех страницах. Это может быть ссылка на страницу помощи, контактная информация или страница FAQ, которая всегда расположена в одном и том же месте (например, в заголовке или нижнем колонтитуле) и доступна [60], [61].
Помогите пользователям избегать и исправлять ошибки.
Не выполнено: Обнаружение ошибок – WCAG 2.2, 3.3.1 (A)
- Обнаруживаются ли ошибки ввода автоматически и сообщается ли пользователю о неисправном элементе и описывается ли ошибка текстуально?
Текущий код контактной формы не содержит механизмов для обнаружения или сообщения об ошибках. Если пользователь отправляет форму с ошибками (например, пустые обязательные поля, недействительный формат электронной почты), не гарантируется, что:
- Ошибка вообще будет обнаружена (отсутствует валидация).
- Неисправное поле будет программно помечено как таковое (например, для скринридера) [62].
- Будет предоставлено четкое текстовое описание ошибки и связано с полем [63], [64].
Это приводит к тому, что пользователи, особенно те, кто зависит от вспомогательных технологий, могут не заметить, что произошла ошибка, какое поле затронуто или как ее можно исправить.
Описание проблемы на примере поля формы
Типичное поле ввода в текущем коде не предлагает структуры для отображения или программного сообщения об ошибках.
Для выполнения WCAG 3.3.1 после валидации (на стороне клиента или сервера) в случае ошибки необходимо четко идентифицировать затронутое поле ввода и описать ошибку. Это обычно делается с помощью:
- Визуального выделения (например, красной рамки).
- Установки атрибута
aria-invalid="true"на неисправном элементе<input>[62]. Это сигнализирует вспомогательным технологиям о состоянии ошибки. - Отображения текстового сообщения об ошибке в непосредственной близости от поля.
- Связывания элемента
<input>с сообщением об ошибке через атрибутaria-describedby[65]. Значение атрибута должно соответствоватьidэлемента, содержащего сообщение об ошибке. Скринридеры затем обычно сначала зачитывают метку, затем тип поля, а затем текст ошибки, связанный черезaria-describedby.
- Проблемное место
- Код, каким он должен быть:
<div>
<input
type="email"
id="contact-email"
name="contact-email"
placeholder="Your Email Address"
/>
</div>
<div class="form-group has-error">
<label for="contact-email">Your Email Address</label>
<input
type="email"
id="contact-email"
name="contact-email"
placeholder="Your Email Address"
required
aria-invalid="true"
aria-describedby="email-error-message"
/>
<div id="email-error-message" class="error-message" role="alert">
Пожалуйста, введите Ваш адрес электронной почты в следующем формате:
primer@email.com. Это поле является обязательным.
</div>
</div>
Задачи:
- Реализовать логику валидации на стороне клиента и/или сервера для контактной формы (например, проверка на пустые обязательные поля, корректный формат электронной почты).
- При возникновении ошибки: Динамически установить (например, с помощью JavaScript) атрибут
aria-invalid="true"на неисправном элементе<input>или<textarea>. - Отобразить четкое текстовое сообщение об ошибке в непосредственной близости от неисправного поля. Дать этому элементу сообщения об ошибке уникальный
id. - Добавить атрибут
aria-describedbyк неисправному элементу<input>/<textarea>, значение которого указывает наidсоответствующего сообщения об ошибке. - Убедиться, что ошибка также визуально четко распознаваема (например, цветом, иконкой, выделением поля и/или сообщения об ошибке).
- Удалить
aria-invalid="true"иaria-describedby(или скрыть сообщение об ошибке), как только ошибка будет исправлена.
Не выполнено: Метки или инструкции – WCAG 2.2, 3.3.2 (A)
- Имеют ли все элементы управления, требующие ввода пользователем, связанные метки (Labels) или инструкции?
Поля ввода (<input>, <textarea>) в контактной форме не имеют явных, программно связанных элементов <label>. Вместо этого используются атрибуты placeholder, чтобы намекнуть на назначение полей. Это проблематично и недостаточно по нескольким причинам [16], [67]:
- Мимолетность: Текст заполнителя исчезает, как только пользователь начинает ввод, из-за чего информация об ожидаемом содержимом теряется.
- Распознавание вспомогательными технологиями: Заполнитель не надежно распознается всеми комбинациями браузеров/скринридеров как доступное имя (Accessible Name) для поля [67]. Однако доступное имя имеет решающее значение, чтобы пользователи скринридеров знали, какое поле они редактируют.
- Контраст: Текст заполнителя часто имеет низкий цветовой контраст с фоном, что затрудняет читаемость для пользователей с нарушениями зрения.
- Назначение: Заполнители в первую очередь предназначены для кратких указаний или примеров формата, а не в качестве замены постоянной метки.
Без корректных меток отсутствует существенная программная связь между описанием и полем ввода [16].
Описание проблемы и код
Текущий код показывает поля ввода без соответствующих элементов <label>.
Стандартным и наиболее надежным решением для предоставления меток для полей формы является использование элемента <label>. Связывая атрибут for метки с id соответствующего элемента ввода (<input>, <textarea>, <select>), устанавливается однозначная программная связь [16]. Эта связь позволяет вспомогательным технологиям правильно зачитывать метку, когда поле получает фокус. Кроме того, пользователи мыши выигрывают от того, что клик по метке устанавливает фокус в соответствующее поле ввода.
- Проблемное место
- Код, каким он должен быть:
<div class="contact-form">
<div>
<input type="text" placeholder="Your Name" />
</div>
<div>
<input type="email" placeholder="Your Email Address" />
</div>
<div>
<textarea rows="6" placeholder="Your Message"></textarea>
</div>
<div>
<button class="submit-button" type="button">Send Message</button>
</div>
</div>
<div class="contact-form">
<div class="form-group">
<label for="contact-name">Your Name</label>
<input
type="text"
id="contact-name"
name="contact-name"
placeholder="напр. Иван Иванов"
required
autocomplete="name"
/>
</div>
<div class="form-group">
<label for="contact-email">Your Email Address</label>
<input
type="email"
id="contact-email"
name="contact-email"
placeholder="напр. [удаленный адрес электронной почты]"
required
autocomplete="email"
/>
</div>
<div class="form-group">
<label for="contact-message">Your Message</label>
<textarea
id="contact-message"
name="contact-message"
rows="6"
placeholder="Чем мы можем Вам помочь?"
required
></textarea>
</div>
<div>
<button class="submit-button" type="submit">Send Message</button>
</div>
</div>
Задачи:
- Добавить видимый элемент
<label>для каждого элемента<input>и<textarea>в контактной форме. - Присвоить каждому полю ввода уникальный
id. - Установить атрибут
forкаждого элемента<label>наidсоответствующего поля ввода, чтобы установить программную связь [16]. - Если необходимы дополнительные инструкции (например, о требуемых форматах или длине), предоставить их в виде видимого текста рядом с полем (например, под меткой или полем ввода) и при необходимости дополнительно связать их через
aria-describedby(см. также SC 3.3.1 [69] и 3.3.3). Использовать заполнители только для кратких, несущественных указаний или примеров.
Не выполнено: Предложение по ошибке – WCAG 2.2, 3.3.3 (AA)
- При пустых обязательных полях предлагаете ли Вы подсказку (например, «Это поле не должно быть пустым»)? (Обнаружение ошибок в целом отсутствует, поэтому предполагается: Нет)
- Если требуется определенный формат данных, предлагаете ли Вы исправление?
- Если допустимы только определенные значения (например, список выбора), предоставляете ли Вы соответствующее указание или предложение? (Таких полей нет)
Поскольку обнаружение ошибок не реализовано (см. 3.3.1 [69]), также не делаются предложения по исправлению [70]. Если пользователь, например, вводит недействительный адрес электронной почты, он (предположительно) не получит специфического сообщения, которое поможет ему исправить ошибку (например, «Пожалуйста, введите действительный адрес электронной почты в формате name@domain.de.»).
Выполнено: Предотвращение ошибок (Юридические, Финансовые, Данные) – WCAG 2.2, 3.3.4 (AA)
- При юридически или финансово значимых действиях (например, покупка, налоговая декларация) предлагаете ли Вы возможность изменить или отменить? (Не применимо)
- Если пользовательские данные удаляются или изменяются, можно ли это отменить или подтвердить? (Не применимо)
- При тестах (например, экзаменах, опросниках) даете ли Вы возможность проверить ответы или изменить их, прежде чем они будут окончательно отправлены? (Не применимо)
Выполнено: Избыточный ввод – WCAG 2.2, 3.3.7 (A)
- Избегаете ли Вы двойного ввода в рамках одного процесса или автоматически заполняете ранее введенные данные? (Не применимо для простой контактной формы)
Выполнено: Доступная аутентификация (Минимум) – WCAG 2.2, 3.3.8 (AA)
- Избегаете ли Вы чисто когнитивных шагов проверки (например, сложных паролей, головоломок) или предлагаете альтернативы? (Аутентификация отсутствует)
Достаточно ли надежен Ваш веб-сайт?
Четвертый и последний краеугольный камень доступности — это надежность (Robust) [3].
Этот аспект гарантирует, что Ваш веб-сайт останется совместимым с будущими технологиями и будет правильно интерпретироваться различными пользовательскими агентами, включая вспомогательные технологии.
Соблюдая чистый HTML и веб-стандарты, Вы повышаете долговечность и доступность Вашего веб-сайта.
Максимизируйте совместимость со всеми технологиями, которые используют пользователи.
Не выполнено: Парсинг – WCAG 2.2, 4.1.1 (A)
- Вложены ли элементы согласно их спецификации, имеют ли открывающие и закрывающие теги и нет ли двойных атрибутов/ID?
Хотя явная валидация не проводилась, серьезные семантические ошибки (использование div для всего) указывают на то, что HTML-структура, вероятно, не соответствует спецификациям для правильного использования элементов. Валидный парсинг, вероятно, обеспечен, но корректное применение HTML фундаментально нарушено.
Задачи:
- Проверить код с помощью HTML-валидатора (например, W3C Nu HTML Checker).
- Использовать корректные семантические элементы (см. 1.3.1).
Не выполнено: Имя, роль, значение – WCAG 2.2, 4.1.2 (A)
- Используете ли Вы стандартизированные компоненты пользовательского интерфейса (например, HTML-формы) в соответствии со спецификацией WHATWG HTML [74], чтобы имя/роль были распознаваемы?
- Если Вы переназначаете или переписываете стандартные компоненты, следите ли Вы за корректной разметкой имени/роли?
- Если Вы используете стандартные компоненты на языке программирования, обеспечиваете ли Вы, чтобы имя/роль могли быть считаны через API? (Не применимо)
- Если Вы программируете собственные компоненты пользовательского интерфейса, предоставляете ли Вы имя/роль/состояние через ARIA или API доступности? (ARIA не используется)
Этот критерий нарушается во многих местах [75], [76]:
- Навигация и ссылки в нижнем колонтитуле: Используются
<div>и<span>вместо<a>. Роль («Ссылка») отсутствует. - Заголовки:
<div>вместо<h1><h6>. Роль («Заголовок») отсутствует. - FAQ:
<div>используется как интерактивный триггер вместо<button>. Роль («Кнопка») и состояние (aria-expanded) отсутствуют. - Поля формы: Отсутствие
<label>приводит к тому, что доступное имя полей не может быть правильно определено. - Слайдер/Маркиз: Не определены роли (например,
role="region",aria-live) или состояния, которые делают функцию понятной для вспомогательных технологий. - Поля формы: Отсутствие
<label>приводит к тому, что доступное имя полей не может быть правильно определено. - Слайдер/Маркиз: Не определены роли (например,
role="region",aria-live) или состояния, которые делают функцию понятной для вспомогательных технологий.
Задачи:
- Использовать нативные HTML-элементы для их предполагаемого назначения (Ссылки, Кнопки, Заголовки, Списки, Элементы форм).
- Там, где нативных элементов недостаточно (например, для пользовательских виджетов, таких как аккордеон FAQ), реализовать корректные ARIA-роли, свойства и состояния (
role,aria-label,aria-expanded,aria-controlsи т. д.). - Обеспечить, чтобы все поля формы получали доступное имя через правильно связанные элементы
<label>.
Не выполнено: Сообщения о состоянии – WCAG 2.2, 4.1.3 (AA)
- Выводите ли Вы сообщения о состоянии (например, «Успех» или «Данные сохранены») таким образом, чтобы вспомогательные технологии воспринимали их без фокусировки? (Сообщения о состоянии не реализованы)
- Появляются ли сообщения об ошибках или предупреждения (например, ошибки валидации) также программно воспринимаемо (
role="alert"или аналогично)? - Объявляется ли прогресс (например, полоса загрузки) в реальном времени с помощью роли или Live-Region (например,
role="progressbar"илиrole="log")?** (Индикаторы прогресса не реализованы)
Как было описано ранее, отсутствует обработка ошибок. Если добавляются сообщения об ошибках, они должны быть реализованы таким образом, чтобы вспомогательные технологии (например, скринридеры) автоматически воспринимали их, не требуя от пользователя ручного перемещения фокуса. Обычно это делается с использованием role="alert" или aria-live регионов [77].
Задачи:
- Динамически появляющиеся сообщения о состоянии и ошибках (например, после отправки формы) размещать в контейнере с
role="alert"илиrole="status"(в зависимости от срочности), чтобы они объявлялись скринридерам.
Сейчас проверены все 55 требований WCAG 2.2 на Вашем веб-сайте. Веб-сайт не выполнил 20 из 55 критериев WCAG 2.2. Поэтому Ваш веб-сайт пока не может считаться соответствующим [78].
Все задачи в сводке
Альтернативы изображений и медиа
Alt-Текст / Декоративные изображения
- Создать содержательные альтернативные тексты для всех информативных изображений (Hero, Слайдер, Функции, Чередующиеся разделы, Как это работает) и разместить их в атрибуте
alt[4], [5]. - Проверить, действительно ли отдельные изображения являются чисто декоративными, и явно пометить их
alt=""[6].
Семантическая структура и ошибки HTML
Валидация HTML и структура
- Проверить код с помощью HTML-валидатора (например, W3C Nu HTML Checker) и исправить ошибки [71].
- Использовать корректные семантические HTML-элементы для структуры страницы (
<header>,<nav>,<main>,<section>,<footer>,<article>) [10]. - Иерархически корректно разметить заголовки с помощью
<h1>-<h6>[12], [13].
Списки и группировки
- Структурировать навигационные меню, списки функций, списки шагов, списки FAQ и т. д. как списки HTML (
<ul>/<ol>с<li>) [14].
Разделы и ориентиры (Landmarks)
- Проверить все важные содержательные разделы и при необходимости пометить их как ориентиры с помощью
aria-labelилиaria-labelledby, если нативных элементов, таких как<nav>,<main>, недостаточно [10].
Атрибуты ARIA и интерактивные элементы
Оптимизировать интерактивные элементы
- Реализовать интерактивные элементы (навигационные ссылки, триггеры FAQ, ссылки в нижнем колонтитуле) как нативные ссылки (
<a>сhref) или кнопки (<button>) [31], [44]. - Для интерактивных компонентов, таких как аккордеон FAQ, использовать ARIA-атрибуты (
aria-expanded,aria-controls,role="region"для содержимого) [15]. - Динамически появляющиеся сообщения о состоянии и ошибках (например, после отправки формы) размещать в контейнере с
role="alert"илиrole="status"[77].
Навигация и доступность с клавиатуры
Быстрый доступ и навигация
- Реализовать ссылку «Перейти к содержанию» (Skip-to-Content) как первый фокусируемый элемент (визуально скрытый до фокуса) [40].
- Убедиться, что цель каждой ссылки (через видимый текст ссылки или ARIA-атрибуты) однозначно распознаваема (после преобразования в
<a>) [43]. - Предоставить как минимум один дополнительный способ навигации (Карта сайта, Поиск или согласованные меню) [45], [46], [47].
Фокус и управление с клавиатуры
- Определить в CSS хорошо видимые стили
:focusдля всех интерактивных элементов (ссылок, кнопок, полей форм и т. д.) [50]. - Убедиться, что все интерактивные элементы доступны и управляемы с клавиатуры (Навигация, FAQ, Управление слайдером/маркизом) [31].
Контраст, дизайн и визуальные требования
Контраст текста и нетекстового содержимого
- Настроить цветовые контрасты для текста (заполнители, кнопки, Hero) в соответствии с WCAG AA (4.5:1 для обычного, 3:1 для крупного текста) [23], [24].
- Обеспечить контраст для элементов управления (границы полей форм, индикатор фокуса) в соответствии с WCAG AA (3:1) [28], [29].
Анимация и движение
- Для слайдера и маркиза добавить элементы управления для остановки/приостановки, которые доступны с клавиатуры [34], [35].
- Уважать CSS-медиазапрос
prefers-reduced-motionи при необходимости отключать анимации.
Формы и поля ввода
Метка и цель ввода
- Для каждого поля ввода в контактной форме добавить видимый элемент
<label>и правильно его связать (for/id) [16]. - Добавить подходящие атрибуты
autocompleteдля полей, таких как Имя (name) и Электронная почта (email) [20].
Обработка ошибок
- Реализовать надежную обработку ошибок для контактной формы [63].
- Программно обозначать неисправные поля (
aria-invalid="true") [62]. - Предоставить текстовые сообщения об ошибках, связать их с полем (
aria-describedby) [65] и предлагать исправления [70]. - Объявлять сообщения об ошибках с помощью
role="alert"или аналогичного для скринридеров [77].
Прочие и общесистемные меры
Помощь
- Предоставить согласованный механизм помощи на всех страницах (например, ссылка на FAQ/Контакты в нижнем колонтитуле) [60].
Документация
- Создать (честную) декларацию о доступности и опубликовать ее на веб-сайте.
Если Вы реализуете все эти задачи, Ваш веб-сайт с большой вероятностью сможет достичь презумпции соответствия.
Вывод
Всего было проверено 55 отдельных критериев из WCAG 2.2 A и AA, которые необходимы для соблюдения законодательных требований [1].
- Выполненные критерии: 35
- Невыполненные критерии: 20
Веб-сайт имеет серьезные недостатки в отношении доступности и далеко не соответствует требованиям WCAG 2.2 AA [78]. Проблемы прослеживаются через все четыре принципа доступности (Воспринимаемость, Управляемость, Понятность, Надежность) [3]:
- Воспринимаемость: Отсутствие текстовых альтернатив для изображений, недостаточный цветовой контраст, дефектная семантическая структура, которая скрывает отношения и информацию.
- Управляемость: Важные части веб-сайта (Навигация, FAQ) недоступны с клавиатуры, фокус не виден, движущееся содержимое (Слайдер, Маркиз) не может быть остановлено, и отсутствует ссылка пропуска (Skip-Link).
- Понятность: Формы неправильно помечены, ошибки не сообщаются или сообщаются неадекватно, и отсутствуют альтернативные пути навигации, а также согласованная помощь.
- Надежность: Неправильное использование HTML и отсутствие ARIA, где это необходимо, приводят к тому, что вспомогательные технологии не могут правильно интерпретировать страницу.
Этот демонстрационный веб-сайт в его текущем состоянии крайне недоступен. Однако он очень хорошо иллюстрирует типичные барьеры, которые могут возникнуть в реальных веб-проектах. Реализация перечисленных задач потребует фундаментальной переработки кодовой базы, в частности, внедрения корректных семантических HTML-структур и реализации стандартных паттернов взаимодействия для навигации, форм и динамического содержимого.
Надеюсь, этот отчет поможет Вам понять выявленные барьеры и определить необходимые шаги для улучшения доступности. Если у Вас возникнут вопросы, пожалуйста, свяжитесь со мной.
Ограничение ответственности
- Не является юридической заменой: Этот аудит не представляет собой юридическую консультацию. Все содержимое и рекомендации были тщательно проверены и созданы по мере наших знаний, однако не может быть предоставлено гарантии полноты, актуальности и правильности.
- Ответственность за реализацию: Исключительно заказчик несет ответственность за надлежащую, полную и корректную реализацию рекомендаций.
- Объем ответственности: Любая ответственность ограничивается умышленным или грубо небрежным поведением. В частности, исключаются требования о возмещении ущерба, вызванного легкой небрежностью.
Если у Вас возникнут вопросы относительно объема лицензии, использования содержимого или ответственности, пожалуйста, свяжитесь со мной.