Реалізація ARIA-атрибутів для доступності сайту

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація ARIA-атрибутів для доступності сайту
Середня
~2-3 робочих дні
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Реалізація ARIA-атрибутів для доступності сайту

ARIA (Accessible Rich Internet Applications) — набір HTML-атрибутів, які розширюють семантику елементів для допоміжних технологій. Використовується коли нативної HTML-семантики недостатньо — переважно для спеціальних інтерактивних компонентів.

Перше правило ARIA

Не використовувати ARIA, якщо можна обійтись нативним HTML. Нативні елементи вже мають вбудовану доступність:

<!-- Погано — ARIA-костилі на div -->
<div role="button" tabindex="0" aria-pressed="false">Перемикач</div>

<!-- Добре — нативна кнопка -->
<button type="button">Перемикач</button>

<!-- Погано -->
<div role="heading" aria-level="2">Заголовок</div>

<!-- Добре -->
<h2>Заголовок</h2>

Ключові ARIA-атрибути

Ролі:

<div role="alert">Помилка при збереженні</div>      <!-- важливе повідомлення -->
<div role="status">Збережено успішно</div>         <!-- не критичне сповіщення -->
<nav role="navigation" aria-label="Основна">...</nav> <!-- навігаційний блок -->
<div role="dialog" aria-modal="true">...</div>    <!-- модальне вікно -->
<ul role="listbox">...</ul>                        <!-- список вибору -->

Стани:

<button aria-expanded="false" aria-controls="dropdown-menu">Меню</button>
<ul id="dropdown-menu" aria-hidden="true">...</ul>

<input type="checkbox" aria-checked="mixed">     <!-- проміжний стан -->
<button aria-pressed="true">Жирний</button>      <!-- toggle-кнопка -->
<input aria-disabled="true">                    <!-- візуально відключено -->
<div aria-busy="true">Завантаження...</div>

Зв'язки між елементами:

<!-- aria-labelledby — заголовок елемента -->
<section aria-labelledby="section-title">
    <h2 id="section-title">Про компанію</h2>
</section>

<!-- aria-describedby — додаткове описання -->
<input id="password" type="password"
       aria-describedby="password-requirements">
<p id="password-requirements">Мінімум 8 символів, одна цифра</p>

<!-- aria-controls — керує іншим елементом -->
<button aria-controls="panel-1" aria-expanded="false">Показати деталі</button>

<!-- aria-owns — елементи, що не є потомками в DOM -->
<ul role="listbox" aria-owns="option-1 option-2">...</ul>

Live Regions

<!-- Автоматично оголошується екранною читалкою при змінах -->
<div aria-live="polite" aria-atomic="true">
    <!-- Ввічливо: оголосити після поточної мови -->
    Кошик оновлений: 3 товари
</div>

<div aria-live="assertive">
    <!-- Негайно перервати поточну мову — лише для критичних помилок -->
    Помилка: не удалося підключитися до сервера
</div>

<!-- role="status" = aria-live="polite" + aria-atomic="true" -->
<p role="status">Зміни збережені</p>

<!-- role="alert" = aria-live="assertive" -->
<p role="alert">Форма містить помилки</p>

Компонент системи сповіщень з ARIA

function NotificationSystem() {
    const [notifications, setNotifications] = useState<Notification[]>([]);

    return (
        <>
            {/* Регіон для екранної читалки — завжди в DOM */}
            <div
                aria-live="polite"
                aria-atomic="false"
                className="sr-only"
                id="sr-notifications"
            >
                {notifications.map(n => (
                    <p key={n.id}>{n.message}</p>
                ))}
            </div>

            {/* Візуальні сповіщення */}
            <div className="toast-container">
                {notifications.map(n => (
                    <Toast key={n.id} notification={n} />
                ))}
            </div>
        </>
    );
}

Аккордеон

function Accordion({ items }) {
    const [openIndex, setOpenIndex] = useState<number | null>(null);

    return (
        <div>
            {items.map((item, i) => (
                <div key={item.id}>
                    <h3>
                        <button
                            aria-expanded={openIndex === i}
                            aria-controls={`panel-${i}`}
                            id={`header-${i}`}
                            onClick={() => setOpenIndex(openIndex === i ? null : i)}
                        >
                            {item.title}
                        </button>
                    </h3>
                    <div
                        id={`panel-${i}`}
                        role="region"
                        aria-labelledby={`header-${i}`}
                        hidden={openIndex !== i}
                    >
                        {item.content}
                    </div>
                </div>
            ))}
        </div>
    );
}

Таблиці даних

<table>
    <caption>Статистика продажів за Q3 2024</caption>
    <thead>
        <tr>
            <th scope="col">Продукт</th>
            <th scope="col">Продажі</th>
            <th scope="col">Зміна</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row">Продукт A</th>
            <td>1 240</td>
            <td>
                <span aria-label="ріст на 12%">+12%</span>
            </td>
        </tr>
    </tbody>
</table>

Часті помилки

  • aria-hidden="true" на інтерактивних елементах — вони стають недоступні з клавіатури
  • Дублювання нативної семантики: <button role="button"> — надлишкове
  • aria-label на не семантичних div без role — не працює
  • Динамічне оновлення aria-label без aria-live — екранна читалка не помітить

Часові рамки

Додавання ARIA на спеціальні компоненти в існуючому проекті: 2–4 дні залежно від кількості компонентів.