Веб-доступность начинается с корректной HTML-семантики. Preact, как и React, работает поверх обычного HTML, поэтому именно теги определяют, как интерфейс воспринимается вспомогательными технологиями: скринридерами, голосовым управлением, клавиатурной навигацией.
Использование <div> и <span>
вместо семантических элементов лишает интерфейс структуры. Корректные
теги (<header>, <nav>,
<main>, <section>,
<article>, <button>,
<label>, <form>) позволяют
вспомогательным средствам интерпретировать назначение элементов без
дополнительных ухищрений.
В Preact-компонентах это означает:
function Header() {
return (
<header>
<nav>
<ul>
<li><a href="/">Главная</a></li>
</ul>
</nav>
</header>
);
}
Семантика должна закладываться на уровне JSX, а не эмулироваться атрибутами.
Интерфейс должен быть представлен пользователю в форме, которую он способен воспринять.
Любой нетекстовый контент обязан иметь текстовый эквивалент. Для
изображений используется alt, для иконок — либо
aria-label, либо скрытый текст.
<img src="logo.png" alt="Логотип компании" />
Декоративные изображения должны иметь пустой alt, чтобы
скринридеры их игнорировали.
Preact не управляет стилями напрямую, но архитектура компонентов влияет на соблюдение контрастности. Цвет не должен быть единственным способом передачи информации. Ошибки форм, статусы, уведомления должны сопровождаться текстом или иконками с альтернативным описанием.
Все элементы интерфейса обязаны быть доступны с клавиатуры.
В Preact фокус часто ломается из-за условного рендеринга. При монтировании и размонтировании компонентов необходимо контролировать, куда переходит фокус.
const ref = useRef(null);
useEffect(() => {
ref.current?.focus();
}, []);
return <button ref={ref}>Подтвердить</button>;
Порядок фокуса должен соответствовать визуальному порядку элементов,
без хаотичных tabIndex.
<button> всегда предпочтительнее
<div onClick>. Нативные элементы автоматически
поддерживают клавиатуру, фокус и роли доступности.
Плохо:
<div onCl ick={submit}>Отправить</div>
Хорошо:
<button onCl ick={submit}>Отправить</button>
Интерфейс должен быть логичным и предсказуемым.
Каждое поле ввода обязано иметь связанную подпись. Связь достигается
через label и htmlFor.
<label htmlFor="email">Email</label>
<input id="email" type="email" />
Placeholder не заменяет label, так как исчезает при вводе и плохо читается скринридерами.
Сообщения об ошибках должны быть текстовыми и программно доступными. При динамическом появлении ошибок необходимо уведомлять вспомогательные технологии.
<div role="alert">Поле обязательно для заполнения</div>
Контент должен корректно работать с различными пользовательскими агентами и вспомогательными технологиями.
ARIA-атрибуты используются исключительно тогда, когда семантический
HTML не решает задачу. Избыточное применение role,
aria-* приводит к конфликтам.
Пример оправданного использования:
<div role="dialog" aria-modal="true" aria-labelledby="title">
<h2 id="title">Настройки</h2>
</div>
Если компонент можно реализовать через <dialog>,
ARIA не требуется.
Частые перестроения DOM-дерева мешают скринридерам. В Preact важно избегать лишних перерисовок и резких изменений структуры.
Ключи (key) в списках обязательны не только для
производительности, но и для предсказуемости доступности.
items.map(item => (
<li key={item.id}>{item.name}</li>
))
Состояние интерфейса должно отражаться не только визуально, но и программно.
Пример переключателя:
<button
aria-pressed={isOn}
onCl ick={() => setIsOn(!isOn)}
>
{isOn ? 'Включено' : 'Выключено'}
</button>
aria-pressed сообщает текущее состояние вспомогательным
технологиям, синхронизируя UI и логику.
SPA-приложения на Preact часто обновляют контент без перезагрузки страницы. Это нарушает ожидания скринридеров.
Для уведомлений, которые появляются динамически:
<div aria-live="polite">
{message}
</div>
polite подходит для ненавязчивых сообщений,
assertive — для критических.
При смене представлений (роутинг) важно обновлять заголовки страниц
(<h1>) и, при необходимости, вручную переводить фокус
на начало нового контента.
Доступность закладывается на уровне архитектуры:
Компоненты должны быть доступны по умолчанию, без необходимости дорабатывать каждый экземпляр.
Даже корректный код требует проверки. В экосистеме Preact применяются:
Автоматические тесты выявляют лишь часть проблем, но архитектурные ошибки видны уже на уровне JSX.
Preact не ограничивает доступность и не улучшает её автоматически. Он предоставляет минималистичную, предсказуемую среду, где соблюдение принципов веб-доступности полностью зависит от проектирования компонентов, корректной семантики и дисциплины разработки.