Працює
Академія
Стандарти

Як зробити сайт доступним: покроковий план

Покрокова інструкція як зробити сайт доступним: семантичний HTML, alt-тексти, контраст, клавіатура, форми, ARIA, анімації та тестування.

· 6 хв читання

Як зробити сайт доступним: покроковий план

Зробити сайт доступним означає забезпечити, щоб ним могли користуватися всі люди — включаючи тих, хто користується скрін-рідером, навігує лише клавіатурою, має порушення зору, слуху або когнітивні особливості. Це не потребує переробки сайту з нуля — більшість помилок виправляється за 1-2 спринти розробки.

Цей гід охоплює 10 кроків від базової семантики до тестування, з прикладами коду та конкретними критеріями WCAG 2.2.


Крок 1 — Семантичний HTML

Семантичний HTML — це фундамент доступності. Використовуйте HTML-теги за їхнім призначенням:

<!-- ❌ Погано -->
<div class="button" onclick="submit()">Надіслати</div>
<div class="heading">Заголовок розділу</div>

<!-- ✅ Добре -->
<button type="submit">Надіслати</button>
<h2>Заголовок розділу</h2>

Чому це важливо: Скрін-рідери використовують семантику для навігації. <button> автоматично отримує правильну роль, фокус і обробку клавіші Enter/Space. <div> — нічого з цього.

Ключові семантичні елементи:

  • <header>, <nav>, <main>, <footer>, <aside>, <section>, <article> — для landmark-навігації
  • <h1><h6> — для заголовків (лише один <h1> на сторінці)
  • <button> для дій, <a> для переходів
  • <ul>, <ol>, <li> для списків

WCAG: 1.3.1 Info and Relationships (A), 4.1.2 Name, Role, Value (A)


Крок 2 — Alt-тексти для зображень

Кожне значуще зображення потребує альтернативного тексту (alt). Декоративні зображення мають порожній alt="".

<!-- ❌ Погано -->
<img src="chart.png" />
<img src="logo.png" alt="image" />

<!-- ✅ Добре -->
<img
  src="chart.png"
  alt="Діаграма: 73% державних сайтів не відповідають WCAG AA у 2026 році"
/>
<img src="logo.png" alt="ЦМЦІ — Центр моніторингу цифрової інклюзії" />
<img src="divider.png" alt="" />
<!-- декоративне зображення -->

Правила хорошого alt-тексту:

  • Описуйте зміст і функцію, не зовнішній вигляд
  • Для графіків — включайте ключовий висновок
  • Для кнопок-іконок — описуйте дію ("Закрити меню", не "Іконка X")
  • Максимум ~125 символів; для складних зображень — використовуйте <figcaption>

WCAG: 1.1.1 Non-text Content (A)

Факт: 55% з 1 мільйона перевірених сайтів (WebAIM Million) мають хоча б одне зображення без alt-тексту.


Крок 3 — Контраст кольорів (мінімум 4.5:1)

Вимоги WCAG щодо контрасту:

Тип текстуМінімум (AA)Підвищений (AAA)
Звичайний текст (менше 18pt / 14pt bold)4.5:17:1
Великий текст (18pt+ / 14pt+ bold)3:14.5:1
Компоненти UI та графіка3:1
/* ❌ Погано: сірий #999 на білому #fff = 2.85:1 */
color: #999999;
background: #ffffff;

/* ✅ Добре: темно-сірий #595959 на білому = 7:1 */
color: #595959;
background: #ffffff;

Інструменти перевірки контрасту:

  • WebAIM Contrast Checker
  • Colour Contrast Analyser (десктопний застосунок)
  • Вбудований інструмент у Chrome DevTools (Inspect → Accessibility)

WCAG: 1.4.3 Contrast (Minimum) (AA), 1.4.6 Contrast (Enhanced) (AAA)


Крок 4 — Навігація клавіатурою

Тест: закрийте мишу і спробуйте виконати типові дії лише клавіатурою:

  • Tab — перехід між інтерактивними елементами
  • Shift+Tab — назад
  • Enter / Space — активація кнопок/посилань
  • Стрілки — навігація всередині компонентів (меню, вкладки)
  • Escape — закрити модальне вікно

Найпоширеніші проблеми клавіатурної навігації:

<!-- ❌ Пастка для клавіатури — не можна вийти -->
<div role="dialog">
  <!-- фокус застряє тут, немає кнопки закриття, Escape не працює -->
</div>

<!-- ✅ Правильно — модальне вікно -->
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
  <h2 id="dialog-title">Підтвердження</h2>
  <button>Підтвердити</button>
  <button onclick="closeDialog()">Скасувати</button>
  <!-- Escape також закриває через JS -->
</div>

Skip-link — перший елемент на сторінці, що дозволяє пропустити навігацію:

<a href="#main-content" class="skip-link">Перейти до основного контенту</a>
<!-- ... header, nav ... -->
<main id="main-content"></main>
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
}
.skip-link:focus {
  top: 0; /* з'являється при фокусі */
}

WCAG: 2.1.1 Keyboard (A), 2.1.2 No Keyboard Trap (A), 2.4.1 Bypass Blocks (A)


Крок 5 — Структура заголовків (H1–H6)

Заголовки — це навігаційна структура для скрін-рідерів. Правила:

  • Один H1 на сторінці — назва сторінки
  • Ієрархія не порушується — не стрибайте з H2 до H4
  • Заголовки несуть зміст, а не є стилістичним інструментом
<!-- ❌ Погано -->
<h1>Назва сайту</h1>
<h3>Головний заголовок сторінки</h3>
<!-- пропущено h2 -->
<h2>Підзаголовок</h2>

<!-- ✅ Добре -->
<h1>Каталог товарів</h1>
<h2>Електроніка</h2>
<h3>Смартфони</h3>
<h3>Ноутбуки</h3>
<h2>Одяг</h2>
<h3>Чоловічий</h3>

Перевірте структуру заголовків розширенням HeadingsMap для Chrome/Firefox.

WCAG: 1.3.1 Info and Relationships (A), 2.4.6 Headings and Labels (AA)


Крок 6 — Доступні форми (labels)

Кожне поле форми повинно мати асоційований підпис:

<!-- ❌ Погано — placeholder не є label -->
<input type="email" placeholder="Email" />

<!-- ✅ Добре — явний label -->
<label for="email">Email</label>
<input type="email" id="email" name="email" />

<!-- ✅ Альтернатива — aria-label -->
<input type="search" aria-label="Пошук по сайту" placeholder="Введіть запит" />

Повідомлення про помилки:

<!-- ❌ Погано — лише колір -->
<input type="email" class="error" />

<!-- ✅ Добре — текстове повідомлення -->
<label for="email">Email</label>
<input
  type="email"
  id="email"
  aria-describedby="email-error"
  aria-invalid="true"
/>
<p id="email-error" role="alert">
  Введіть коректну email-адресу (наприклад, [email protected])
</p>

WCAG: 1.3.1 Info and Relationships (A), 3.3.1 Error Identification (A), 3.3.2 Labels or Instructions (A)


Крок 7 — ARIA атрибути

Перше правило ARIA: не використовуйте ARIA, якщо нативний HTML справляється.

ARIA потрібний для:

  • Кастомних компонентів (dropdown, tabs, accordion)
  • Динамічного контенту (повідомлення, оновлення)
  • Зв'язку між елементами
<!-- Кнопка з підказкою -->
<button aria-label="Видалити товар Чоловіча куртка">
  <svg aria-hidden="true">...</svg>
</button>

<!-- Accordion -->
<button aria-expanded="false" aria-controls="section1">Розділ 1</button>
<div id="section1" hidden>Вміст розділу</div>

<!-- Live region для оновлень -->
<div aria-live="polite" aria-atomic="true">
  <!-- Динамічно оновлюваний контент -->
</div>

Детальний гайд: ARIA атрибути для розробників

WCAG: 4.1.2 Name, Role, Value (A)


Крок 8 — Адаптивність (zoom 200%)

Сайт має коректно відображатись при збільшенні до 200% без горизонтального скролу і без втрати контенту.

/* ❌ Погано — фіксована ширина блокує zoom */
.container {
  width: 960px;
  overflow: hidden;
}

/* ✅ Добре — адаптивна ширина */
.container {
  max-width: 1200px;
  width: 100%;
}

/* Не заблоковуйте zoom в мета-тегу */
/* ❌ */ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
/* ✅ */ <meta name="viewport" content="width=device-width, initial-scale=1">

WCAG: 1.4.4 Resize Text (AA), 1.4.10 Reflow (AA)


Крок 9 — Анімації (prefers-reduced-motion)

Анімації можуть викликати запаморочення або епілептичні напади. Поважайте налаштування користувача:

/* Базові анімації */
.card {
  transition: transform 0.3s ease;
}

/* Вимкнути для користувачів з відповідним налаштуванням */
@media (prefers-reduced-motion: reduce) {
  .card {
    transition: none;
  }

  /* Або мінімальна анімація */
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

Перевірте: Налаштування → Доступність → "Зменшити рух" (macOS), або Windows → Параметри → Спрощення доступу → "Показувати анімацію".

WCAG: 2.3.3 Animation from Interactions (AAA, але критично важливо)


Крок 10 — Тестування

Автоматизоване (виявляє ~40% помилок):

  • ЦМЦІ /scan — безкоштовний WCAG аудит
  • axe DevTools — Chrome/Firefox розширення
  • Lighthouse (вбудований у Chrome DevTools)

Ручне тестування:

  • Навігація лише Tab/Enter/Escape
  • Збільшення до 200% у браузері
  • Вимкнення CSS (перевірити логічний порядок)
  • Перевірка без кольору (grayscale у налаштуваннях)

Скрін-рідер:

Чеклист перед запуском:

  • Всі зображення мають alt-тексти або alt=""
  • Контраст всіх текстів ≥ 4.5:1
  • Навігація клавіатурою через весь сайт без пасток
  • Видимий фокус-стан на всіх елементах
  • Всі поля форм мають <label>
  • Структура заголовків логічна (один H1, без пропусків)
  • <html lang="uk"> встановлено
  • Skip-link на початку сторінки
  • Zoom 200% без горизонтального скролу
  • Скрін-рідер може прочитати весь контент

Корисні посилання

Чи була ця стаття корисною?