Посібник для розробників з ARIA-міток, які справді допомагають
ARIA-мітки — це не магічний шар доступності. За правильного використання вони роблять елементи керування зрозумілими. За недбалого використання вони приховують корисний текст і створюють заплутані інтерфейси.
Зміст
- ARIA-мітки призначені для назв, а не для вибачень
- Доступна назва простими словами
- Перше правило: віддавайте перевагу нативному HTML і видимим міткам
- Коли `aria-label` — правильний інструмент
- Коли `aria-label` — неправильний інструмент
- Звертайтеся до `aria-labelledby`, коли видимий текст уже існує
- Використовуйте `aria-describedby` для допоміжного тексту, а не для назви
- Повторюваним елементам керування потрібні унікальні назви
- Не маркуйте все підряд
- Перевіряйте обчислену назву, а не лише код
- Практичний чекліст для рев’ю
- Тиха дисципліна хорошої ARIA
ARIA-мітки призначені для назв, а не для вибачень
ARIA корисна, але її часто використовують як латочку для неясного HTML. Саме тут команди потрапляють у пастку.
Найпоширеніший приклад — aria-label. Виглядає безпечно: додати рядок, задовольнити лінтер і рухатися далі. Але доступна назва — це не декор. Це назва, яку багато допоміжних технологій показують або озвучують користувачам, коли ті навігують кнопками, посиланнями, полями форм, заголовками, орієнтирами та елементами керування.
Якщо ця назва розмита, дубльована, застаріла або відрізняється від видимої мітки, інтерфейс стає складнішим у використанні. Іноді ще гірше: aria-label може перевизначити кращий текст, який уже був у DOM.
Мета не в тому, щоб додати більше ARIA. Мета — зробити назву, роль, стан і призначення кожного елемента інтерфейсу зрозумілими.
Доступна назва простими словами
Більшість інтерактивних елементів мають доступну назву. Скринридери використовують цю назву, щоб озвучити, що це за елемент.
Наприклад:
<button>Save changes</button>
Скринридер може оголосити щось на кшталт: «Save changes, кнопка». Роль походить від нативного елемента button. Назва походить із тексту всередині нього.
Це ідеальний випадок: видимий текст і доступна назва збігаються.
Атрибути ARIA для маркування стають корисними, коли видимий інтерфейс не надає повної назви або коли назва має походити з іншого елемента. Основні атрибути:
aria-label: надає рядок безпосередньо на елементі.aria-labelledby: вказує на один або кілька елементів, текст яких стає назвою.aria-describedby: вказує на допоміжний описовий текст, а не на основну назву.
Ці три атрибути пов’язані, але не взаємозамінні.
Перше правило: віддавайте перевагу нативному HTML і видимим міткам
Якщо ви можете розмістити видимий текст на елементі керування, спершу зробіть саме це.
Це краще:
<button>Delete invoice</button>
Ніж це:
<button aria-label="Delete invoice">
<svg aria-hidden="true" focusable="false">...</svg>
</button>
Другий шаблон валідний для кнопки лише з іконкою. Але якщо дизайн може витримати видимий текст, він допомагає всім: користувачам скринридерів, користувачам голосового керування, людям із когнітивним навантаженням, тим, хто швидко переглядає сторінку, і тим, хто користується інструментами перекладу.
Це повторювана тема в роботі над доступністю. Нативний HTML і видимі афорданси розв’язують більше проблем, ніж приховані метадані. Той самий принцип застосовується до семантики кнопок загалом; якщо ваша команда проводить аудит елементів керування UI, наш чекліст доступних вебкнопок добре доповнить цей посібник.
Коли aria-label — правильний інструмент
Використовуйте aria-label, коли елементу потрібна доступна назва і немає відповідного видимого тексту, на який можна послатися.
Класичний випадок — кнопка лише з іконкою:
<button aria-label="Search">
<svg aria-hidden="true" focusable="false" viewBox="0 0 24 24">
<!-- icon -->
</svg>
</button>
Це прийнятно. Видима іконка натякає на пошук, але сам SVG-шлях не надає надійної назви. aria-label її додає.
Інші доречні випадки:
- Кнопка закриття, представлена лише символом «X».
- Навігаційний орієнтир, якому потрібна конкретніша назва, наприклад
aria-label="Product". - Повторюваний елемент керування, де видимий контекст не є частиною тексту кнопки.
Наприклад:
<nav aria-label="Primary">
...
</nav>
<nav aria-label="Footer">
...
</nav>
Обидва є навігаційними орієнтирами, але їхні мітки допомагають користувачам розрізняти їх під час переходу між орієнтирами.
Коли aria-label — неправильний інструмент
Не додавайте aria-label лише тому, що тест каже, ніби елементу потрібна мітка. Спершу виправте розмітку.
Погано:
<div role="button" tabindex="0" aria-label="Submit">Submit</div>
Краще:
<button>Submit</button>
Перший приклад створює зайву роботу. Тепер вам потрібно відтворити поведінку клавіатури, вимкнені стани, поведінку у формах і очікування, які нативні кнопки вже забезпечують.
Також уникайте використання aria-label, щоб перейменовувати видимий текст у спосіб, який змінює значення.
<button aria-label="Delete invoice">Remove</button>
Це виглядає дрібницею, але може заплутати користувачів, які покладаються на голосове введення. Якщо видима кнопка має текст «Remove», а її доступна назва — «Delete invoice», користувач, який намагається сказати «натисни Remove», може не отримати очікуваного результату. Вимога WCAG щодо «label in name» існує саме з цієї причини: видимий текст зазвичай має міститися в доступній назві.
Краща версія:
<button aria-label="Remove invoice">Remove</button>
Часто ще краще:
<button>Remove invoice</button>
Звертайтеся до aria-labelledby, коли видимий текст уже існує
Якщо текст мітки вже є на сторінці, aria-labelledby зазвичай кращий за aria-label.
Приклад:
<h2 id="billing-title">Billing address</h2>
<section aria-labelledby="billing-title">
...
</section>
Доступна назва секції тепер походить із видимого заголовка. Ви уникаєте дублювання рядків, що зменшує ризик помилок перекладу та застарілих міток.
Це особливо корисно для груп полів форми:
<fieldset aria-labelledby="shipping-speed-title">
<legend id="shipping-speed-title">Shipping speed</legend>
<label>
<input type="radio" name="shipping" value="standard">
Standard
</label>
<label>
<input type="radio" name="shipping" value="express">
Express
</label>
</fieldset>
У багатьох випадках нативного legend достатньо без ARIA. Суть у тому, що видимі мітки мають бути провідними. ARIA має з’єднувати наявне значення, а не створювати його другу приватну версію.
Використовуйте aria-describedby для допоміжного тексту, а не для назви
Опис — це не мітка.
Розгляньте це поле:
<label for="password">Password</label>
<input id="password" type="password" aria-describedby="password-help">
<p id="password-help">Use at least 12 characters.</p>
Доступна назва — «Password». Опис — «Use at least 12 characters». Скринридер може озвучити обидва, але вони виконують різні ролі.
Не робіть так:
<input type="password" aria-label="Use at least 12 characters">
Це називає поле за інструкцією, а не за поняттям. Користувач, який навігує формою, спершу хоче знати, що це за поле, а вже потім — які обмеження застосовуються.
Ця різниця важлива і в станах помилки:
<label for="email">Email</label>
<input
id="email"
type="email"
aria-invalid="true"
aria-describedby="email-error"
>
<p id="email-error">Enter an email address in the format [email protected].</p>
Мітка залишається стабільною. Повідомлення про помилку стає допоміжним контекстом.
Повторюваним елементам керування потрібні унікальні назви
Списки й картки — це місця, де ARIA-мітки часто стають необхідними.
Погано:
<button>Delete</button>
<button>Delete</button>
<button>Delete</button>
Користувач скринридера, який навігує кнопками, може тричі почути «Delete, кнопка» без жодного контексту.
Добре:
<button aria-label="Delete report: Q4 revenue">Delete</button>
<button aria-label="Delete report: Hiring plan">Delete</button>
<button aria-label="Delete report: Vendor list">Delete</button>
Це легітимне використання aria-label: видимий текст залишається лаконічним, а доступна назва містить об’єкт.
Але використовуйте цей шаблон обережно. Якщо назва об’єкта видима поруч, aria-labelledby може бути зручнішим для підтримки:
<article>
<h3 id="report-q4">Q4 revenue</h3>
<button aria-labelledby="delete-q4 report-q4" id="delete-q4">Delete</button>
</article>
Доступна назва стає «Delete Q4 revenue». Це дає змогу не дублювати назву звіту в атрибуті.
Не маркуйте все підряд
Не кожен елемент потребує ARIA-мітки.
Статичний текст зазвичай не потребує. Декоративні іконки — теж. Контейнери — ні, якщо тільки вони не мають змістовної ролі орієнтира або віджета. Надмірне маркування може зробити сторінку шумною та складнішою для навігації.
Для зображень використовуйте модель, специфічну для зображень: змістовним зображенням потрібен корисний alt; декоративним зображенням потрібен порожній alt="". Не використовуйте ARIA-мітки як заміну якісному тексту для зображень. Якщо ваша команда змішує ці поняття, поверніться до прагматичного alt-тексту для зображень і відокремте альтернативи для зображень від назв елементів керування.
Поширена помилка — додавати aria-label до кожного SVG. Якщо SVG всередині кнопки, а кнопка вже має назву, іконку зазвичай слід приховати від допоміжних технологій:
<button aria-label="Open menu">
<svg aria-hidden="true" focusable="false">...</svg>
</button>
Інакше користувач може почути надлишкові або дивні оголошення залежно від поєднання браузера й допоміжної технології.
Перевіряйте обчислену назву, а не лише код
Помилки доступності часто переживають code review, бо розмітка виглядає правдоподібно.
Сучасні інструменти розробника в браузерах можуть показувати обчислене дерево доступності. У Chrome, Edge, Firefox і Safari перевірте елемент і знайдіть інформацію про доступність, зокрема роль, назву та опис. Ви перевіряєте три речі:
- Чи роль така, як ви очікуєте?
- Чи доступна назва зрозуміла й конкретна?
- Чи опис допомагає, не замінюючи назву?
Потім протестуйте кілька сценаріїв із реальним скринридером. Вам не потрібно ставати штатним експертом із допоміжних технологій, щоб виявляти базові проблеми. На macOS вбудований VoiceOver. На Windows широко використовують безкоштовний NVDA. На мобільних пристроях, де це доречно, тестуйте з VoiceOver на iOS і TalkBack на Android.
Автоматизовані інструменти корисні, але вони не можуть надійно визначити, чи «Open», «Read more» або «Delete» мають достатньо контексту. Сприймайте автоматизацію як сітку, а не як суддю. Це схоже на аудит продуктивності: звіт може вказати на підозрілі ділянки, але вам усе одно потрібно інтерпретувати вплив. Той самий спокійний підхід, який ми радимо для читання звіту Lighthouse без паніки, застосовується і тут.
Практичний чекліст для рев’ю
Перед випуском ARIA-міток запитайте:
- Чи можна замість цього використати нативний HTML?
- Чи є видимий текст, який слід використати як мітку?
- Якщо видимий текст існує, чи містить його доступна назва?
- Чи повторювані елементи керування залишаються унікальними під час навігації поза візуальним контекстом?
- Чи допоміжний текст під’єднаний через
aria-describedby, а не примусово втиснутий у мітку? - Чи декоративні іконки приховані від допоміжних технологій?
- Чи хтось перевірив обчислену доступну назву в інструментах розробника браузера?
- Чи було виконано хоча б один прохід критичним сценарієм із реальним скринридером?
Цей чекліст виявляє більшість проблем із мітками до того, як вони стануть проблемами користувачів.
Тиха дисципліна хорошої ARIA
Хороша робота з ARIA рідко буває драматичною. Здебільшого це стриманість.
Використовуйте справжні кнопки. Використовуйте справжні мітки. Узгоджуйте видимі та доступні назви. Додавайте aria-label лише тоді, коли немає кращого видимого джерела. Використовуйте aria-labelledby, коли сторінка вже містить потрібний текст. Використовуйте aria-describedby для допоміжних інструкцій і помилок.
Вебплатформа дає розробникам багато безкоштовно, коли ми використовуємо її напряму. ARIA існує для прогалин. Майстерність — у тому, щоб знати, коли прогалина справді є.