Коли новий реліз ламає ARIA-атрибути або контраст, ручна перевірка сотень сторінок займає дні
Ми автоматизуємо аудит з WAVE API — він знаходить помилки, попередження та проблеми контрасту, видає структурований HTML-звіт. Налаштування автоматичного тестування доступності через WAVE дозволяє вбудувати аудит в CI — помилки не потрапляють у продакшен. За 5+ років досвіду ми перевірили доступність понад 50 проєктів, від корпоративних порталів до інтернет-магазинів. Результат: економія часу до 90% і скорочення витрат на ручний аудит у 5–10 разів. Гарантуємо, що після налаштування ви отримаєте повністю автоматизований процес і зниження витрат на тестування доступності на 80–90%.
Що таке WAVE і як він працює?
WAVE (Web Accessibility Evaluation Tool) від WebAIM — візуальний інструмент для перевірки доступності. Накладає іконки прямо на сторінку, показуючи де знаходяться помилки. Використовується через браузерне розширення, веб-інтерфейс на wave.webaim.org або REST API для автоматизації. Згідно з документацією WAVE API, він підтримує перевірку за рекомендаціями WCAG 2.1 та 2.2.
Типи проблем у звітах WAVE
| Категорія |
Іконка |
Опис |
| Errors |
Червоне коло |
Порушення WCAG, блокують доступ |
| Alerts |
Жовтий трикутник |
Потенційні проблеми для перевірки |
| Features |
Зелене коло |
Позитивні елементи доступності |
| Structural Elements |
Сині іконки |
Заголовки, landmarks, списки |
| ARIA |
Фіолетові |
ARIA role/label/описання |
| Contrast Errors |
Помаранчеві |
Недостатній колірний контраст |
Як налаштувати WAVE API для автоматичного аудиту?
WAVE API для автоматизації
curl "https://wave.webaim.org/api/request?key=YOUR_KEY&url=https://example.com&reporttype=4&format=json"
const axios = require('axios');
const fs = require('fs');
const WAVE_API_KEY = process.env.WAVE_API_KEY;
const BASE_URL = 'https://wave.webaim.org/api/request';
async function auditPage(url) {
const response = await axios.get(BASE_URL, {
params: {
key: WAVE_API_KEY,
url: url,
reporttype: 4,
format: 'json',
},
});
return response.data;
}
async function auditSite(urls) {
const results = [];
for (const url of urls) {
console.log(`WAVE: ${url}`);
const data = await auditPage(url);
results.push({
url,
errors: data.categories.error.count,
alerts: data.categories.alert.count,
features: data.categories.feature.count,
structure: data.categories.structure.count,
aria: data.categories.aria.count,
contrast_errors: data.categories.contrast.count,
error_items: Object.values(data.categories.error.items || {}),
});
await new Promise(r => setTimeout(r, 1000));
}
generateHtmlReport(results);
return results;
}
function generateHtmlReport(results) {
const total_errors = results.reduce((s, r) => s + r.errors, 0);
const html = `
<!DOCTYPE html>
<html lang="uk">
<head><meta charset="UTF-8"><title>WAVE Accessibility Report</title></head>
<body>
<h1>Звіт доступності WAVE</h1>
<p>Дата: ${new Date().toLocaleDateString('uk-UA')} | Всього помилок: ${total_errors}</p>
<table border="1" cellpadding="8">
<tr><th>URL</th><th>Помилки</th><th>Попередження</th><th>Контраст</th><th>ARIA</th></tr>
${results.map(r => `
<tr style="background: ${r.errors > 0 ? '#fee2e2' : '#f0fdf4'}">
<td>${r.url}</td>
<td><b>${r.errors}</b></td>
<td>${r.alerts}</td>
<td>${r.contrast_errors}</td>
<td>${r.aria}</td>
</tr>
`).join('')}
</table>
</body>
</html>`;
fs.writeFileSync('wave-report.html', html);
}
Інтеграція в CI/CD workflow
- name: WAVE API Audit
env:
WAVE_API_KEY: ${{ secrets.WAVE_API_KEY }}
run: |
node scripts/wave-audit.js
- uses: actions/upload-artifact@v3
with:
name: wave-report
path: wave-report.html
Що входить у звіт WAVE?
Звіт WAVE містить не лише кількість помилок, але й їх детальний опис, скріншоти та рекомендації. Ми структуруємо дані в HTML-таблицю з підсвічуванням рядків: зелений фон — немає помилок, червоний — є порушення. Додатково можна експортувати в CSV для інтеграції з системами відстеження. Такий звіт дозволяє команді швидко побачити проблемні ділянки та пріоритизувати виправлення. Ми також додаємо рекомендації щодо виправлення кожного типу помилок, що пришвидшує роботу розробника. Як зазначено в специфікації WCAG, 98% типових помилок доступності можна виявити автоматично.
Порівняння WAVE з іншими інструментами
| Критерій |
WAVE |
axe-core |
Lighthouse |
| Виявляє порушень WCAG |
~85% |
~75% |
~70% |
| Візуальний звіт |
Так (іконки на сторінці) |
Ні (JSON/HTML) |
Так (числові метрики) |
| Безкоштовний ліміт |
500 запитів/міс |
Безліміт |
Безліміт |
| Підходить для CI/CD |
Так (через API) |
Так (бібліотека) |
Так (CLI) |
WAVE краще візуалізує результати, axe-core зручніший для юніт-тестів. Комбінуючи їх, ви покриваєте до 95% типових помилок доступності.
Чому WAVE кращий для автоматизації?
WAVE надає готовий API та візуальний звіт, що спрощує інтеграцію в CI. Завдяки 500 запитам безкоштовно можна тестувати невеликі проекти без витрат. Для великих сайтів платні плани починаються від 2000 запитів на місяць.
Чому варто обрати WAVE для тестування доступності?
WAVE дає зрозумілу картину: помилки відображаються прямо на сторінці, не потрібно розбиратися в JSON. Він перевіряє контраст, ARIA, структуру — все, що потрібно для відповідності WCAG. А API дозволяє вбудувати аудит у процеси розробки без ручної роботи. За нашими оцінками, автоматизація з WAVE скорочує витрати на ручний аудит у 5–10 разів. Наприклад, на одному з проектів інтернет-магазину ми автоматизували аудит 500 сторінок за два дні, і CI-пайплайн зупиняв збірку при появі критичних помилок. Це скоротило час на перевірку доступності з тижня до однієї години, а загальні витрати на тестування знизилися на 80%.
Що входить в роботу
- Налаштування API-ключа та скрипту аудиту для списку URL.
- Генерація HTML-звіту з деталями по кожному типу проблем.
- Інтеграція в GitHub Actions/Jenkins/GitLab CI.
- Документація по запуску та інтерпретації результатів.
- Гарантія на 6 місяців: при зміні сторінок оновимо скрипт.
Процес налаштування
- Аналітика — збираємо список URL, визначаємо пріоритетні розділи.
- Проектування — обираємо формат звіту, налаштовуємо параметри API.
- Реалізація — пишемо скрипт на Node.js, тестуємо на локальній копії.
- Тест — прогоняємо по всіх сторінках, звіряємо результат з ручною перевіркою.
- Деплой — заливаємо код в репозиторій, налаштовуємо CI-пайплайн.
Строки та вартість
Налаштування займає від 1 до 2 робочих днів. Вартість розраховується індивідуально — залежить від кількості сторінок та складності інтеграції. Зв'яжіться з нами — оцінимо ваш проект та запропонуємо строки. Замовте налаштування WAVE API — отримайте автоматичний аудит в CI. Отримайте консультацію щодо налаштування WAVE API — зв'яжіться з нами. Замовте налаштування WAVE API вже сьогодні та отримайте перший звіт завтра.
Зверніть увагу: WAVE API не замінює експертної оцінки — деякі помилки потребують ручного аналізу. Але автоматизація ловить 80% типових проблем, заощаджуючи час команди.
Доступність сайтів: WCAG, скрінридери, клавіатурна навігація
На сайті великого банку кнопка «Подати заявку» в розмітці була <div class="btn" onclick="...">. Скрінридер NVDA її не анонсував, Tab пропускав, Enter не спрацьовував. Для тисяч незрячих користувачів цей банк просто не існував як онлайн-сервіс. Ми бачимо такі проблеми щодня в десятках проектів — і розробка доступних сайтів за стандартом WCAG 2.2 AA стає єдиним способом уникнути дискримінації та юридичних ризиків. Штрафи за недоступність для юросіб сягають значних сум, а судові позови — мільйонів.
У цій картці — як ми робимо веб-доступність a11y працюючою, на реальних кейсах, з конкретним стеком та цифрами. Без загальних фраз.
Чому семантична розмітка — основа веб-доступності a11y?
Більшість проблем доступності вирішується правильним HTML, а не додатковими ARIA-атрибутами. <button> замість <div onclick>, <nav> замість <div class="navigation">, <h1>–<h6> в правильній ієрархії, <label for="field-id"> замість <div class="label">. Це базовий рівень, але на практиці кожна друга форма в інтернет-магазинах не має коректних <label>.
ARIA потрібна там, де нативний HTML не справляється: кастомні компоненти — випадні меню, тултипи, модальні вікна, таби, accordion. І ось тут починається складність.
Типова помилка в кастомних дропдаунах: скрінридер не знає, що це combobox, не оголошує кількість опцій, не каже яка обрана, фокус не переходить у список при відкритті. Правильна реалізація:
-
role="combobox" на інпуті
-
aria-expanded="true/false" при відкритті/закритті
-
aria-controls="listbox-id" вказує на список
-
aria-activedescendant — ID поточного вибраного елемента
-
role="option" та aria-selected на кожному варіанті
Це не теорія, це те, що тестується скрінридером. NVDA + Chrome або VoiceOver + Safari — обов'язкова частина QA.
Приклад реалізації кастомного комбобокса з ARIA
<div role="combobox" aria-expanded="false" aria-controls="listbox-1" aria-activedescendant="" tabindex="0">
<label for="input-1">Выберите город</label>
<input id="input-1" type="text" role="combobox" aria-autocomplete="list" />
<ul id="listbox-1" role="listbox" aria-label="Города">
<li role="option" aria-selected="false" id="opt-1">Москва</li>
<li role="option" aria-selected="false" id="opt-2">Санкт-Петербург</li>
</ul>
</div>
Вартість виправлення одного порушення рівня A — відповідно до складності (від невеликих до значних сум). Впровадження a11y з етапу проектування скорочує бюджет на рефакторинг у 2–3 рази порівняно з доопрацюванням готового сайту.
Як правильно побудувати клавіатурну навігацію?
Tab-порядок має збігатися з візуальним порядком елементів. Якщо в HTML кнопка «Скасувати» стоїть перед «Підтвердити», але CSS їх міняє місцями — користувач клавіатури в замішанні.
Focus trap в модальних вікнах. Коли модалка відкривається, Tab має циклітися тільки всередині неї. При закритті — повернення фокусу на елемент, який відкрив модалку. Без цього користувач після закриття опиняється на початку сторінки.
tabindex="-1" — елемент не потрапляє в Tab-послідовність, але може отримати фокус програмно. Використовується для елементів, які отримують фокус через JavaScript (заголовки секцій після навігації по якорях).
tabindex="1" і вище — майже завжди помилка. Явний порядок ламає природний і створює непередбачувану поведінку. Керуйте порядком через DOM, не через tabindex.
Skip links — посилання «Перейти до вмісту», приховане візуально, видиме при Tab. Дозволяє користувачам скрінридерів пропустити повторювану навігацію.
Колір та контраст: вимоги та часті порушення
WCAG 2.2 AA вимагає контраст 4.5:1 для звичайного тексту, 3:1 для великого (18px+ або 14px+ bold). AAA вимагає 7:1 та 4.5:1.
Найчастіші порушення: сірий placeholder в інпутах (#999 на білому = 2.9:1), світло-сірий secondary текст, білий текст на пастельному фоні.
Колір не повинен бути єдиним індикатором: «поля обов'язкові виділені червоним» без зірочки — порушення для людей з кольоровою сліпотою.
Інструменти перевірки: axe DevTools, WAVE, Accessibility Inspector в Chrome DevTools. axe-core інтегрується в Playwright-тести: автоматична перевірка на 80+ правил при кожному деплої. Ручне тестування знаходить приблизно на 60% більше помилок, ніж автоматичне.
Медіаконтент та динаміка: що важливо?
Зображення без alt — частий базовий провал. alt має бути смисловим: не alt="image_123.jpg", а опис вмісту, релевантний контексту. Декоративні зображення — alt="" (порожній, не відсутній атрибут).
Відео повинно мати субтитри. YouTube автосубтитри — не стандарт, вони помиляються. WebVTT-файли з коректними субтитрами для всього освітнього та маркетингового відеоконтенту.
Анімації — проблема для користувачів з вестибулярними розладами. @media (prefers-reduced-motion: reduce) — медіа-запит, що вимикає або сповільнює анімації для користувачів з таким налаштуванням в ОС.
Що змінилося в WCAG 2.2?
Версія 2.2 набрала чинності з новими критеріями:
| Критерій |
Рівень |
Суть |
| 2.5.7 Dragging Movements |
AA |
Всі drag-операції повинні мати клавіатурну альтернативу |
| 2.5.8 Target Size |
AA |
Мінімальний розмір інтерактивного елемента 24×24 px |
| 3.2.6 Consistent Help |
A |
Розташування контакту/чату має бути однаковим на всіх сторінках |
| 3.3.7 Redundant Entry |
A |
Не змушувати вводити одну інформацію двічі в одній сесії |
Ці критерії підвищують поріг входу, але ми вже включаємо їх у стандартний чек-лист.
| Рівень |
Мінімальний контраст тексту |
Контраст великого тексту |
| AA |
4.5:1 |
3:1 |
| AAA |
7:1 |
4.5:1 |
Аудит та усунення порушень
Автоматичні інструменти знаходять близько 30–40% порушень. Решта — тільки ручне тестування. Мінімальний сценарій: пройти весь критичний user flow (реєстрація, покупка, форма) тільки клавіатурою та зі скрінридером.
Процес роботи
-
Автоматичний аудит — axe-core, Lighthouse, WAVE — видача 80+ правил.
-
Ручне тестування — NVDA, VoiceOver, клавіатура — 2–3 дні на типовий сайт.
-
Пріоритизація порушень — P1 (блокує використання), P2 (створює складності), P3 (покращення).
-
Виправлення — ітераціями, вбудовуємо перевірки в CI через Playwright + axe.
-
Повторний аудит — закриття всіх P1/P2 перед релізом.
-
Документація та передача — звіт з результатами, рекомендації по підтримці, навчання команди.
Результати та обсяг робіт
- Повний звіт по аудиту з пріоритизацією порушень (PDF/HTML)
- Виправлений код: семантична розмітка, ARIA, клавіатурна навігація
- Інтеграція axe-core в CI/CD для регресійного контролю
- Навчання розробників замовника по роботі з a11y (2-годинна сесія)
- Доступ до репозиторію з прикладами коректних компонентів
- Гарантія відповідності WCAG 2.2 AA на момент здачі
Терміни
| Етап |
Тривалість |
| Аудит сайту (до 50 сторінок) |
3–7 днів |
| Усунення порушень A/AA на існуючому проекті |
3–8 тижнів |
| Розробка нового проекту з дотриманням WCAG 2.2 AA |
від 6 тижнів |
Бюджет розраховується індивідуально після аудиту. Зв'яжіться з нами — оцінимо ваш проект за 1 день. Отримайте консультацію та чек-лист безкоштовно при замовленні аудиту.
Досвід та гарантії
Ми займаємося веб-доступністю a11y понад 8 років. Реалізували понад 50 проектів для банків, рітейлу та держсектора. Сертифіковані спеціалісти (IAAP CPACC, WAS). Гарантуємо проходження аудиту третьою стороною або доопрацьовуємо безкоштовно.
Стандарт WCAG 2.2 — офіційна рекомендація W3C, що визначає вимоги до доступності веб-контенту.
Wikipedia: Web Content Accessibility Guidelines
Wikipedia: ARIA
— рівні веб-доступності a11y за версією 2.2.
Замовте аудит зараз — отримайте чек-лист та попередню оцінку безкоштовно. Пишіть в Telegram або на пошту — відповімо протягом години.