Введение
Доступность (Accessibility) - это принцип, согласно которому веб-приложения должны быть доступны для всех пользователей, независимо от их физических или когнитивных возможностей. В этой статье мы рассмотрим основные принципы и практики создания доступных веб-приложений.
Почему важна доступность?
- Инклюзивность: Доступ для всех пользователей
- Юридические требования: Соответствие законодательству
- Бизнес-выгода: Расширение аудитории
- Этика: Социальная ответственность
Основные принципы доступности
1. Воспринимаемость
Семантическая разметка
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| <!-- Правильная семантическая структура -->
<header>
<nav aria-label="Основное меню">
<ul>
<li><a href="/">Главная</a></li>
<li><a href="/about">О нас</a></li>
<li><a href="/contact">Контакты</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h1>Заголовок статьи</h1>
<p>Содержание статьи...</p>
</article>
</main>
|
2. Понятность
Четкая структура контента
1
2
3
4
5
6
7
8
9
10
11
| <!-- Структурированный контент -->
<section aria-labelledby="section-title">
<h2 id="section-title">Название раздела</h2>
<div class="content">
<p>Основной текст...</p>
<aside>
<h3>Дополнительная информация</h3>
<p>Дополнительный контент...</p>
</aside>
</div>
</section>
|
ARIA-атрибуты
1. Основные ARIA-роли
Использование ролей
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| <!-- Примеры ARIA-ролей -->
<div role="banner">
<h1>Логотип сайта</h1>
</div>
<div role="navigation" aria-label="Основное меню">
<ul>
<li><a href="/">Главная</a></li>
<li><a href="/about">О нас</a></li>
</ul>
</div>
<div role="main">
<article>
<h2>Основной контент</h2>
<p>Текст статьи...</p>
</article>
</div>
|
2. ARIA-состояния и свойства
Управление состоянием
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| <!-- Примеры ARIA-состояний -->
<button
aria-expanded="false"
aria-controls="dropdown-menu"
aria-haspopup="true">
Меню
</button>
<div
id="dropdown-menu"
role="menu"
aria-hidden="true">
<a href="#" role="menuitem">Пункт 1</a>
<a href="#" role="menuitem">Пункт 2</a>
</div>
|
Формы и валидация
1. Доступные формы
Структура формы
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| <form aria-labelledby="form-title">
<h2 id="form-title">Регистрация</h2>
<div class="form-group">
<label for="name">Имя:</label>
<input
type="text"
id="name"
name="name"
required
aria-required="true"
aria-describedby="name-error">
<div id="name-error" class="error" role="alert"></div>
</div>
<button type="submit">Отправить</button>
</form>
|
2. Валидация и обратная связь
Обработка ошибок
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| // Валидация формы
function validateForm(event) {
const form = event.target;
const nameInput = form.querySelector('#name');
const errorDiv = form.querySelector('#name-error');
if (!nameInput.value.trim()) {
errorDiv.textContent = 'Пожалуйста, введите имя';
nameInput.setAttribute('aria-invalid', 'true');
return false;
}
errorDiv.textContent = '';
nameInput.setAttribute('aria-invalid', 'false');
return true;
}
|
Клавиатурная навигация
1. Управление фокусом
Настройка фокуса
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| // Управление фокусом
function handleFocus() {
const focusableElements = document.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
focusableElements.forEach(element => {
element.addEventListener('focus', () => {
element.classList.add('focus-visible');
});
element.addEventListener('blur', () => {
element.classList.remove('focus-visible');
});
});
}
|
2. Стили фокуса
CSS для фокуса
1
2
3
4
5
6
7
8
9
10
| /* Стили для фокуса */
.focus-visible {
outline: 2px solid #007bff;
outline-offset: 2px;
}
/* Скрытие фокуса только для мыши */
:focus:not(:focus-visible) {
outline: none;
}
|
Мультимедиа и альтернативный контент
1. Изображения
Альтернативный текст
1
2
3
4
5
6
7
8
9
10
11
12
| <!-- Правильное использование alt -->
<img
src="logo.png"
alt="Логотип компании Example Corp"
width="150"
height="50">
<!-- Декоративное изображение -->
<img
src="decoration.png"
alt=""
role="presentation">
|
2. Видео и аудио
Доступные медиа-элементы
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| <!-- Видео с субтитрами -->
<video controls>
<source src="video.mp4" type="video/mp4">
<track
kind="subtitles"
src="subtitles.vtt"
srclang="ru"
label="Русские субтитры"
default>
<p>Ваш браузер не поддерживает видео.</p>
</video>
<!-- Аудио с транскрипцией -->
<audio controls>
<source src="audio.mp3" type="audio/mpeg">
<p>
<a href="transcript.txt">Скачать транскрипцию</a>
</p>
</audio>
|
Тестирование доступности
1. Автоматизированное тестирование
Использование инструментов
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| // Пример использования axe-core
import axe from 'axe-core';
function runAccessibilityTests() {
axe.run(document.body, {
rules: {
'color-contrast': { enabled: true },
'document-title': { enabled: true }
}
}).then(results => {
if (results.violations.length > 0) {
console.error('Найдены проблемы доступности:', results.violations);
}
});
}
|
2. Ручное тестирование
Чек-лист проверки
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| // Чек-лист для ручного тестирования
const accessibilityChecklist = {
keyboardNavigation: () => {
// Проверка навигации с клавиатуры
return document.querySelectorAll(':focus-visible').length > 0;
},
colorContrast: () => {
// Проверка контрастности цветов
return checkColorContrast();
},
screenReader: () => {
// Проверка работы с программами чтения с экрана
return testScreenReaderCompatibility();
}
};
|
Заключение
Создание доступных веб-приложений - это не только требование законодательства, но и важный аспект создания качественного пользовательского опыта. Следуйте принципам доступности и регулярно тестируйте ваше приложение на соответствие стандартам.