В современной веб-разработке тема доступности (accessibility, a11y) слишком часто напоминает поход к стоматологу: все знают, что это жизненно необходимо, но откладывают до последнего момента. Большинство команд вспоминает про стандарты WCAG только тогда, когда юридический отдел получает претензию от регулятора или когда крупный корпоративный заказчик требует сертификат соответствия.
В панике разработчики начинают хаотично навешивать в разметку атрибуты aria-label, role="button" на обычные теги <div> и надеяться, что скринридеры как-нибудь разберутся. В итоге получается классический карго-культ: формально атрибуты есть, но слепой пользователь или человек с моторными нарушениями физически не может отправить форму или закрыть всплывающее окно клавишей Escape.
Чтобы разорвать этот порочный круг, ведущая британская консалтинговая компания по инклюзивному дизайну выпустила открытую библиотеку TetraLogical Accessible Components Library (исходный код доступен в репозитории на GitHub). Её автор — признанный эксперт по цифровой доступности Крейг Эбботт (Craig Abbott).
Давай разберёмся, почему эта библиотека заслуживает самого пристального внимания любого фронтендера, независимо от того, пишешь ли ты на React, Vue, Svelte или чистом JavaScript.
Восемь базовых UI-паттернов без фреймворковых зависимостей
Первое и самое ценное архитектурное решение команды TetraLogical — полный отказ от фреймворков и сторонних рантаймов. В библиотеке нет зависимостей от React, Tailwind, Redux или тяжелых полифилов. Все компоненты написаны на нативном семантическом HTML5, чистом CSS и лаконичном Vanilla JavaScript.
В стартовый комплект вошли восемь фундаментальных интерактивных паттернов, из которых строится 90% пользовательских интерфейсов:
- Accordion (аккордеон): раскрывающиеся секции с корректным переключением состояния клавишами вверх/вниз.
- Alerts (уведомления): всплывающие системные сообщения с живыми регионами
aria-live="polite". - Breadcrumbs (хлебные крошки): цепочка навигации с разметкой тегом
<nav aria-label="...">. - Disclosure (спойлер): компактная кнопка показа и скрытия дополнительного контента.
- Modal Dialog (модальное диалоговое окно): изолированное окно с жестким удержанием фокуса (Focus Trap) и блокировкой фонового контента.
- Pagination (пагинация): постраничный переключатель с озвучиванием текущей страницы через
aria-current="page". - Tabs (вкладки): система табов с правильной связкой ролей
tablist,tab,tabpanelи клавиатурной навигацией стрелками. - Tooltip (тултип): всплывающая подсказка, открывающаяся при фокусе и закрывающаяся по клавише Escape. Если тебя интересует развитие нативных тултипов в браузерах, взгляни также на наш разбор Firefox 157 и нативной стилизации тултипов.
Анатомия доступного модального окна на чистом HTML и JS
Давай заглянем внутрь реализации модального окна. В подавляющем большинстве сторонних UI-библиотек модалка — это тяжелый div, обмазанный обработчиками событий. В TetraLogical за основу взят нативный элемент HTML5 <dialog> в сочетании с продуманной защитой фокуса:
<!-- Разметка доступного диалогового окна -->
<dialog id="confirm-modal" aria-labelledby="modal-title" aria-describedby="modal-desc" class="c-modal">
<div class="c-modal__inner">
<h2 id="modal-title">Подтверждение удаления аккаунта</h2>
<p id="modal-desc">Это действие необратимо. Все ваши проекты будут удалены навсегда.</p>
<div class="c-modal__actions">
<button type="button" class="btn btn--danger" id="confirm-delete">Удалить навсегда</button>
<button type="button" class="btn btn--secondary" id="cancel-delete">Отмена</button>
</div>
</div>
</dialog>
А вот как выглядит минимальный JavaScript-модуль управления фокусом:
// Контроллер модального окна с ловушкой фокуса
class AccessibleModal {
constructor(dialogElement) {
this.dialog = dialogElement;
this.previousFocus = null;
// Закрытие по клавише Escape с возвратом фокуса
this.dialog.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
e.preventDefault();
this.close();
}
});
}
open() {
this.previousFocus = document.activeElement;
this.dialog.showModal(); // Нативный API браузера с блокировкой фона
// Переводим фокус на первый интерактивный элемент
const firstFocusable = this.dialog.querySelector('button, [href], input, [tabindex="0"]');
if (firstFocusable) firstFocusable.focus();
}
close() {
this.dialog.close();
// Возвращаем фокус на элемент, вызвавший открытие окна!
if (this.previousFocus && typeof this.previousFocus.focus === 'function') {
this.previousFocus.focus();
}
}
}
Обрати внимание на метод close(): возврат фокуса на элемент, открывший модалку — это ключевое требование WCAG 2.2, о котором забывают 8 из 10 разработчиков. Без этого после закрытия окна фокус скринридера улетает в начало страницы, и незрячий пользователь полностью теряет контекст работы.
Автоматизация 97% сценариев доступности через Playwright и Cucumber
Самая впечатляющая инженерная часть проекта TetraLogical — это не сам код компонентов, а система их тестирования.
Исторически тестирование доступности считалось исключительно ручным процессом: нужно было сажать эксперта с включенным скринридером (NVDA под Windows, VoiceOver под macOS) и вручную кликать по интерфейсу. Автоматические линтеры вроде axe-core способны поймать лишь базовые ошибки контрастности и пропущенные атрибуты (не более 30–40% проблем).
Команда Крейга Эбботта пошла дальше: они описали требования к поведению каждого компонента на человекопонятном языке Gherkin через Cucumber и автоматизировали их прогон в браузере с помощью Playwright!
Пример сценария тестирования на Gherkin:
Feature: Клавиатурная навигация в модальном окне
Scenario: Закрытие окна по клавише Escape возвращает фокус
Given модальное окно открыто кликом по кнопке "Удалить"
When пользователь нажимает клавишу "Escape"
Then модальное окно должно быть скрыто
And фокус ввода должен вернуться на кнопку "Удалить"
Благодаря этой связке авторам удалось автоматизировать 97% всех приёмочных критериев WCAG 2.2 для своих компонентов. Тесты проверяют порядок табуляции, обработку клавиш стрелок, видимость фокуса и правильность передачи ролей скринридерам в реальных браузерных движках Chromium, WebKit и Firefox.
Как использовать в своих проектах
Библиотека распространяется под максимально свободной лицензией MIT. Ты можешь использовать её двумя способами:
- Как эталонную обучающую спецификацию: когда ты проектируешь компоненты в своей корпоративной дизайн-системе на React, Vue или Angular, открой репозиторий TetraLogical и просто скопируй правильную HTML-структуру, логику перехвата клавиш и ARIA-атрибуты.
- Как легковесную основу для проектов: подключи нативные скрипты и стили напрямую, оформив их под свой бренд через CSS-переменные без накладных расходов на рантайм фреймворков.
Инклюзивный дизайн — это не благотворительность и не бюрократия. Это показатель инженерной зрелости команды и уважения к каждому пользователю твоего продукта.
