Доступность
Веб-доступность (также известная как a11y) — это практика создания веб-сайтов, которыми может пользоваться любой человек — будь то инвалид, человек с медленным соединением, устаревшим или сломанным оборудованием или просто человек, находящийся в неблагоприятных условиях. Например, добавление субтитров к видео поможет как глухим и слабослышащим пользователям, так и пользователям, которые находятся в шумной обстановке и не слышат свой телефон. Аналогично, убедитесь, что ваш текст не слишком контрастный, это поможет как слабовидящим пользователям, так и тем, кто пытается пользоваться телефоном при ярком солнечном свете.
Готовы начать, но не знаете, с чего начать?
Ознакомьтесь с Руководство по планированию и управлению доступностью веб-сайтов, предоставленным Консорциумом Всемирной паутины (W3C).
Переход к основному содержанию
В верхней части каждой страницы следует добавить ссылку, ведущую непосредственно к основному содержанию, чтобы пользователи могли пропустить материалы, которые повторяются на нескольких веб-страницах.
Обычно это делается в верхней части файла App.vue
, поскольку он будет первым фокусируемым элементом на всех ваших страницах:
template
<span ref="backToTop" tabindex="-1" />
<ul class="skip-links">
<li>
<a href="#main" ref="skipLink" class="skip-link">Перейти к основному содержанию</a>
</li>
</ul>
Чтобы скрыть ссылку, если она не сфокусирована, можно добавить следующий стиль:
css
.skip-links {
list-style: none;
}
.skip-link {
white-space: nowrap;
margin: 1em auto;
top: 0;
position: fixed;
left: 50%;
margin-left: -72px;
opacity: 0;
}
.skip-link:focus {
opacity: 1;
background-color: white;
padding: 0.5em;
border: 1px solid black;
}
При смене маршрута фокус должен возвращаться в начало страницы, перед ссылкой «Пропустить». Это можно сделать, вызвав focus
на шаблонной ссылке backToTop
(при использовании vue-router
):
vue
<script setup>
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const backToTop = ref()
watch(
() => route.path,
() => {
backToTop.value.focus()
}
)
</script>
Подробнее о ссылке перехода к основному содержимому
Структура содержания
Одна из самых важных составляющих доступности — убедиться в том, что дизайн может поддерживать доступную реализацию. Дизайн должен учитывать не только цветовой контраст, выбор шрифта, размер текста и язык, но и то, как структурирован контент в приложении.
Заголовки
Пользователи могут ориентироваться в приложении по заголовкам. Наличие описательных заголовков для каждого раздела вашего приложения облегчает пользователям прогнозирование содержания каждого раздела. Когда речь идет о заголовках, существует несколько рекомендуемых практик обеспечения доступности:
- Расположите заголовки в порядке их ранжирования:
<h1>
-<h6>
- Не пропускайте заголовки внутри раздела
- Используйте настоящие теги заголовков вместо стилизации текста, чтобы придать заголовкам визуальный вид.
template
<main role="main" aria-labelledby="main-title">
<h1 id="main-title">Главный заголовок</h1>
<section aria-labelledby="section-title-1">
<h2 id="section-title-1"> Название раздела </h2>
<h3>Подзаголовок раздела</h3>
<!-- Контент -->
</section>
<section aria-labelledby="section-title-2">
<h2 id="section-title-2"> Название раздела </h2>
<h3>Подзаголовок раздела</h3>
<!-- Контент -->
<h3>Подзаголовок раздела</h3>
<!-- Контент -->
</section>
</main>
Ориентиры
Ориентиры обеспечивают программный доступ к разделам внутри приложения. Пользователи, использующие вспомогательные технологии, могут переходить к каждому разделу приложения и пропускать содержимое. Для достижения этой цели можно использовать ARIA-роли.
HTML | Роль ARIA | Назначение ориентира |
---|---|---|
header | role="banner" | Основной заголовок: название страницы |
nav | role="navigation" | Коллекция ссылок, подходящих для использования при навигации по документу или связанным с ним документам |
main | role="main" | Основное или центральное содержание документа |
footer | role="contentinfo" | Информация об исходном документе: сноски/авторские права/ссылки на заявление о конфиденциальности |
aside | role="complementary" | Поддерживает основной контент, но при этом отделен и имеет смысл для собственного контента |
search | role="search" | В этом разделе размещен функционал поиска по приложению |
form | role="form" | Коллекция элементов, связанных с формой |
section | role="region" | Контент, который актуален и к которому пользователи, скорее всего, захотят перейти. Для этого элемента должна быть указана метка |
Семантические формы
При создании формы вы можете использовать следующие элементы: <form>
, <label>
, <input>
, <textarea>
и <button>
Метки обычно размещаются сверху или слева от полей формы:
template
<form action="/dataCollectionLocation" method="post" autocomplete="on">
<div v-for="item in formItems" :key="item.id" class="form-item">
<label :for="item.id">{{ item.label }}: </label>
<input
:type="item.type"
:id="item.id"
:name="item.id"
v-model="item.value"
/>
</div>
<button type="submit">Отправить</button>
</form>
Обратите внимание, как вы можете включить autocomplete='on'
в элемент формы, и это будет применяться ко всем входным данным в вашей форме. Вы также можете установить разные значения атрибута автозаполнения для каждого ввода.
Метки
Предоставьте метки, описывающие цель всех элементов управления формой; связывание for
и id
:
template
<label for="name">Имя: </label>
<input type="text" name="name" id="name" v-model="name" />
Если вы проверите этот элемент в инструментах разработчика Chrome и откроете вкладку «Доступность» на вкладке «Элементы», вы увидите, как входные данные получают свое имя из метки:
Предупреждение
Хотя вы, возможно, видели, как метки обертывают поля ввода таким образом:
template
<label>
Name:
<input type="text" name="name" id="name" v-model="name" />
</label>
Явная установка меток с соответствующим идентификатором лучше поддерживается вспомогательными технологиями.
aria-label
Вы также можете дать вводимым данным доступное имя с помощью aria-label
.
template
<label for="name">Имя: </label>
<input
type="text"
name="name"
id="name"
v-model="name"
:aria-label="nameLabel"
/>
Не стесняйтесь просмотреть этот элемент в Chrome DevTools, чтобы увидеть, как изменилось доступное имя:
aria-labelledby
Использование aria-labelledby
аналогично aria-label
, за исключением того, что оно используется, если текст метки виден на экране. Он сопрягается с другими элементами по их id
, и вы можете связать несколько id
:
template
<form
class="demo"
action="/dataCollectionLocation"
method="post"
autocomplete="on"
>
<h1 id="billing">Счёт</h1>
<div class="form-item">
<label for="name">Имя: </label>
<input
type="text"
name="name"
id="name"
v-model="name"
aria-labelledby="название счёта"
/>
</div>
<button type="submit">Отправить</button>
</form>
aria-describedby
aria-describedby используется так же, как и aria-labelledby
, но содержит описание с дополнительной информацией, которая может понадобиться пользователю. С его помощью можно описать критерии для любого ввода:
template
<form
class="demo"
action="/dataCollectionLocation"
method="post"
autocomplete="on"
>
<h1 id="billing">Счёт</h1>
<div class="form-item">
<label for="name">Полное имя: </label>
<input
type="text"
name="name"
id="name"
v-model="name"
aria-labelledby="название счёта"
aria-describedby="nameDescription"
/>
<p id="nameDescription">Пожалуйста, укажите имя и фамилию.</p>
</div>
<button type="submit">Отправить</button>
</form>
Вы можете просмотреть описание, заглянув в Chrome DevTools:
Заполнитель
Избегайте использования заполнителей, так как они могут запутать многих пользователей.
Одной из проблем с заполнителями является то, что по умолчанию они не соответствуют критерию цветового контраста; исправление цветового контраста приводит к тому, что в полях ввода заполнитель выглядит как предварительно заполненные данные. Если посмотреть на следующий пример, то можно увидеть, что заполнитель фамилии, отвечающий критериям цветового контраста, выглядит как предварительно заполненные данные:
template
<form
class="demo"
action="/dataCollectionLocation"
method="post"
autocomplete="on"
>
<div v-for="item in formItems" :key="item.id" class="form-item">
<label :for="item.id">{{ item.label }}: </label>
<input
type="text"
:id="item.id"
:name="item.id"
v-model="item.value"
:placeholder="item.placeholder"
/>
</div>
<button type="submit">Отправить</button>
</form>
css
/* https://www.w3schools.com/howto/howto_css_placeholder.asp */
#lastName::placeholder {
/* Chrome, Firefox, Opera, Safari 10.1+ */
color: black;
opacity: 1; /* Firefox */
}
#lastName:-ms-input-placeholder {
/* Internet Explorer 10-11 */
color: black;
}
#lastName::-ms-input-placeholder {
/* Microsoft Edge */
color: black;
}
Лучше всего предоставлять всю информацию, необходимую пользователю для заполнения формы, без каких-либо вводов.
Инструкции
Добавляя инструкции для полей ввода, не забудьте правильно связать их с полем ввода. Вы можете предоставить дополнительные инструкции и связать несколько идентификаторов внутри aria-labelledby
. Это позволяет создавать более гибкие конструкции.
template
<fieldset>
<legend>Using aria-labelledby</legend>
<label id="date-label" for="date">Текущая дата: </label>
<input
type="date"
name="date"
id="date"
aria-labelledby="date-label date-instructions"
/>
<p id="date-instructions">MM/DD/YYYY</p>
</fieldset>
Кроме того, вы можете прикрепить инструкции к вводу с помощью aria-describedby
:
template
<fieldset>
<legend>Using aria-describedby</legend>
<label id="dob" for="dob">Дата рождения: </label>
<input type="date" name="dob" id="dob" aria-describedby="dob-instructions" />
<p id="dob-instructions">MM/DD/YYYY</p>
</fieldset>
Скрытое содержимое
Обычно не рекомендуется визуально скрывать метки, даже если ввод имеет доступное имя. Однако если функциональность ввода может быть понятна из окружающего контента, то визуальную метку можно скрыть.
Давайте посмотрим на это поле поиска:
template
<form role="search">
<label for="search" class="hidden-visually">Поиск: </label>
<input type="text" name="search" id="search" v-model="search" />
<button type="submit">Поиск</button>
</form>
Мы можем это сделать, потому что кнопка поиска поможет визуальным пользователям определить назначение поля ввода.
С помощью CSS мы можем визуально скрыть элементы, но сохранить их доступными для вспомогательных технологий:
css
.hidden-visually {
position: absolute;
overflow: hidden;
white-space: nowrap;
margin: 0;
padding: 0;
height: 1px;
width: 1px;
clip: rect(0 0 0 0);
clip-path: inset(100%);
}
aria-hidden="true"
Добавление aria-hidden="true"
скроет элемент от вспомогательных технологий, но оставит его визуально доступным для других пользователей. Не используйте его на фокусируемых элементах, только на декоративном, дублирующемся или внеэкранном контенте.
template
<p>Это не скрыто от устройств чтения с экрана.</p>
<p aria-hidden="true">Это скрыто от устройств чтения с экрана.</p>
Кнопки
При использовании кнопок внутри формы необходимо установить тип, предотвращающий отправку формы. Вы также можете использовать вход для создания кнопок:
template
<form action="/dataCollectionLocation" method="post" autocomplete="on">
<!-- Buttons -->
<button type="button">Отменить</button>
<button type="submit">Отправить</button>
<!-- Input buttons -->
<input type="button" value="Отменить" />
<input type="submit" value="Отправить" />
</form>
Функциональные изображения
Вы можете использовать эту технику для создания функциональных изображений.
Поля ввода
- Эти изображения будут действовать как кнопки отправки в формах
template<form role="search"> <label for="search" class="hidden-visually">Поиск: </label> <input type="text" name="search" id="search" v-model="search" /> <input type="image" class="btnImg" src="https://img.icons8.com/search" alt="Поиск" /> </form>
Icons
template
<form role="search">
<label for="searchIcon" class="hidden-visually">Поиск: </label>
<input type="text" name="searchIcon" id="searchIcon" v-model="searchIcon" />
<button type="submit">
<i class="fas fa-search" aria-hidden="true"></i>
<span class="hidden-visually">Поиск</span>
</button>
</form>
Стандарты
Инициатива по обеспечению веб-доступности (WAI) Консорциума Всемирной паутины (W3C) разрабатывает стандарты веб-доступности для различных компонентов:
- Руководство по доступности пользовательского агента (UAAG)
- веб-браузеры и медиаплееры, включая некоторые аспекты вспомогательных технологий
- Руководство по обеспечению доступности средств создания (ATAG)
- авторские инструменты
- Руководство по доступности веб-контента (WCAG)
- веб-контент — используется разработчиками, авторскими инструментами и инструментами оценки доступности
Руководство по доступности веб-контента (WCAG)
WCAG 2.1 развивает WCAG 2.0 и позволяет внедрять новые технологии, учитывая изменения в Интернете. W3C рекомендует использовать самую последнюю версию WCAG при разработке или обновлении политики веб-доступности.
WCAG 2.1 Четыре основных руководящих принципа (сокращённо ВУПУ — POUR):
- Воспринимаемость (Perceivable)
- Пользователи должны иметь возможность воспринимать представляемую информацию
- Управляемость (Operable)
- Формы интерфейса, элементы управления и навигации работоспособны
- Понятность (Understandable)
- Информация и работа пользовательского интерфейса должны быть понятны всем пользователям
- Устойчивость (Robust)
- Пользователи должны иметь доступ к контенту по мере развития технологий
Инициатива по обеспечению доступности веб-сайтов – доступные многофункциональные интернет-приложения (WAI-ARIA)
WAI-ARIA W3C предоставляет рекомендации по созданию динамического контента и расширенных элементов управления пользовательским интерфейсом.
Ресурсы
Документация
- WCAG 2.0
- WCAG 2.1
- Доступные многофункциональные интернет-приложения (WAI-ARIA) 1.2
- Практика разработки WAI-ARIA 1.2
Вспомогательные технологии
- Программы чтения с экрана
- Инструменты масштабирования
Тестирование
- Автоматизированные инструменты
- Инструменты для работы с цветом
- Другие полезные инструменты
Пользователи
По оценкам Всемирной организации здравоохранения, 15 % населения Земли имеют ту или иную форму инвалидности, 2-4 % из них — тяжелую. Это примерно 1 миллиард человек во всем мире; таким образом, люди с ограниченными возможностями стали самым многочисленным меньшинством в мире.
Существует огромное количество видов инвалидности, которые можно условно разделить на четыре категории:
- Визуальная - Для таких пользователей могут быть полезны программы чтения с экрана, увеличение экрана, регулирование контрастности экрана или отображение текста шрифтом Брайля.
- Слуховая - Этим пользователям могут помочь субтитры, расшифровки или видео на языке жестов.
- Двигательная - Эти пользователи могут воспользоваться рядом вспомогательных технологий при двигательных нарушениях: программное обеспечение для распознавания голоса, отслеживание глаз, доступ с помощью одного переключателя, головная палочка, переключатель для глотка и затяжки, увеличенную мышь с трекболом, адаптивную клавиатуру или другие вспомогательные технологии.
- Когнитивная - Для таких пользователей полезны дополнительные средства информации, структурная организация содержания, ясный и простой текст.
Ознакомьтесь со следующими ссылками от WebAim, чтобы узнать мнение пользователей: