Screen readers

Atomico — это библиотека для создания веб-компонентов на базе Web Components с реактивной моделью, схожей с React. Одной из ключевых задач при разработке компонентов является обеспечение их доступности для пользователей с особыми потребностями, включая людей, использующих экранные читалки.

ARIA-атрибуты и роль компонентов

Экранные читалки ориентируются на ARIA-атрибуты (Accessible Rich Internet Applications) и стандартные HTML-элементы для определения структуры страницы и интерактивных элементов. Atomico позволяет добавлять эти атрибуты напрямую через JSX-подобный синтаксис.

import { c, html } from "atomico";

function Button({ label, disabled }) {
    return html`
        <button
            role="button"
            aria-label=${label}
            ?disabled=${disabled}
        >
            ${label}
        </button>
    `;
}

Button.props = {
    label: String,
    disabled: Boolean
};

export const button = c(Button);

Ключевые моменты:

  • role определяет семантику элемента.
  • aria-label позволяет задать текст для читалки, когда визуальный текст недостаточен.
  • Префикс ? перед атрибутом (?disabled) автоматически применяет атрибут только если значение истинно.

Фокусировка и управление клавиатурой

Для пользователей экранных читалок критично правильное управление фокусом. Atomico обеспечивает реактивное отслеживание состояния и позволяет управлять атрибутами tabindex и событиями клавиатуры:

function Menu({ items }) {
    let activeIndex = 0;

    function onKeyDown(event) {
        if (event.key === "ArrowDown") activeIndex = (activeIndex + 1) % items.length;
        if (event.key === "ArrowUp") activeIndex = (activeIndex - 1 + items.length) % items.length;
    }

    return html`
        <ul role="menu" @keydown=${onKeyDown}>
            ${items.map((item, index) => html`
                <li
                    role="menuitem"
                    tabindex=${index === activeIndex ? 0 : -1}
                >
                    ${item}
                </li>
            `)}
        </ul>
    `;
}

Особенности:

  • tabindex="0" делает элемент доступным для фокуса.
  • Элементы с tabindex="-1" доступны только программно через скрипт.
  • Обработчики событий клавиатуры (@keydown) позволяют перемещать фокус по элементам меню.

Динамическое обновление контента

Экранные читалки отслеживают изменения DOM, но иногда динамически обновляемый контент нужно явно озвучивать. Для этого применяются ARIA-live регионы:

function Notifications({ messages }) {
    return html`
        <div aria-live="polite">
            ${messages.map(msg => html`<p>${msg}</p>`)}
        </div>
    `;
}
  • aria-live=“polite” сообщает экранной читалке, что новые сообщения можно озвучивать, но не прерывая текущий контент.
  • aria-live=“assertive” используется для критических уведомлений, которые нужно озвучивать немедленно.

Управление сложными компонентами

Для сложных виджетов, таких как табы или аккордеоны, важно поддерживать правильную семантику и фокус:

function Tabs({ tabs }) {
    let activeTab = 0;

    return html`
        <div role="tablist">
            ${tabs.map((tab, index) => html`
                <button
                    role="tab"
                    aria-selected=${index === activeTab}
                    tabindex=${index === activeTab ? 0 : -1}
                    @click=${() => activeTab = index}
                >
                    ${tab.label}
                </button>
            `)}
        </div>
        <div role="tabpanel">
            ${tabs[activeTab].content}
        </div>
    `;
}
  • role=“tablist”, role=“tab”, role=“tabpanel” — стандартные роли для реализации табов.
  • aria-selected отражает текущую выбранную вкладку.
  • Фокус следует автоматически перемещать на активный таб для согласованного поведения с экранными читалками.

Рекомендации по тестированию

  1. Использовать нативные элементы там, где это возможно (<button>, <input>, <ul>).
  2. Проверять доступность через инструменты вроде VoiceOver на macOS или NVDA на Windows.
  3. Проверять ARIA-атрибуты и порядок табуляции.
  4. Следить за реактивностью компонентов: динамически добавляемый контент должен быть озвучен корректно.

Итоговые практики в Atomico

  • Каждый интерактивный компонент должен иметь роль, состояние и метку.
  • Управление фокусом и клавиатурой — обязательное требование.
  • Динамический контент озвучивается через aria-live.
  • Семантика сложных виджетов соблюдается с помощью стандартных ARIA-ролей.

Atomico позволяет сочетать реактивность и гибкость Web Components с полным соблюдением правил доступности, что обеспечивает совместимость с экранными читалками и улучшает UX для всех пользователей.