# P19 · сентябрь 2019 · базовая веб-доступность — тройное ревью
Статус: **принят в публикационный слой 31 июля 2026 года**. Registry применяет
ровно три ревизии по стабильным slug и сохраняет дату и автора базового архива:
- editorial-2019-09-practice-accessibility-basics;
- editorial-2019-09-mechanism-accessibility-basics;
- editorial-2019-09-field-accessibility-basics.
Модуль экспортирует ровно три revision без полей date и
author. При прямом вызове с --print-revisions он
пишет только JSON, совпадающий с import-safe export. Черновик намеренно не
выдаёт план ручной проверки за пройденный реальный прогон со screen reader.
## Проход 1. Факты и техника — пройдено
| Утверждение или решение | Первичный источник | Проверенная граница |
| --- | --- | --- |
| При последовательной навигации порядок фокуса сохраняет смысл и работоспособность операции | [WCAG 2.1, 2.4.3 Focus Order](https://www.w3.org/TR/WCAG21/#focus-order) | Тексты не выдают произвольный положительный tabindex за решение; сначала требуется пройти Tab и Shift+Tab в браузере |
| Интерфейс, которым управляют с клавиатуры, нуждается в режиме с видимым индикатором фокуса | [WCAG 2.1, 2.4.7 Focus Visible](https://www.w3.org/TR/WCAG21/#focus-visible) | Не заявляется достаточность одного CSS-правила: проверяется различимость на реальном фоне при фокусе |
| У автоматически обнаруженной input error должны быть идентифицированы ошибочный элемент и текстовое описание ошибки | [WCAG 2.1, 3.3.1 Error Identification](https://www.w3.org/TR/WCAG21/#error-identification) | Красная рамка не названа текстовой ошибкой; во всех примерах есть видимое объяснение и связь с полем |
| Компонентам интерфейса требуются программно определимые name, role, value или state | [WCAG 2.1, 4.1.2 Name, Role, Value](https://www.w3.org/TR/WCAG21/#name-role-value) | Статья о механизме отличает DOM-узел от проверяемого role/name/state в browser accessibility tree |
| HTML label связывается с form control через for/id либо вложение control | [HTML Standard: label element](https://html.spec.whatwg.org/multipage/forms.html#the-label-element) | Текст рядом с input не объявлен именем сам по себе; пример использует label и уникальный id |
| Положительный tabindex создаёт отдельный относительный порядок последовательной фокусировки | [HTML Standard: tabindex](https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute) | Не обещается, что tabindex «чинит» доступность; маршрут Tab проверяется на собранной странице |
| aria-describedby — список ID для полного description, а aria-errormessage работает вместе с aria-invalid и актуальная ошибка не должна быть скрыта | [WAI-ARIA 1.1: aria-describedby](https://www.w3.org/TR/wai-aria-1.1/#aria-describedby), [WAI-ARIA 1.1: aria-errormessage](https://www.w3.org/TR/wai-aria-1.1/#aria-errormessage) | Пример синхронизирует текст, hidden и aria-invalid; он не заявляет, что сообщение уже было озвучено вспомогательной технологией |
### Честная граница исследования
Источники сверены с нормативными WCAG 2.1, HTML Standard и WAI-ARIA 1.1.
Кодовые фрагменты — воспроизводимые примеры отношений в разметке и локального
состояния, а не отчёт о запуске браузерной автоматизации. Ни screen reader, ни
реальный браузерный прогон страницы в рамках P19 не выполнялись. Поэтому
формулировки «проверить в Accessibility tree» и «пройти клавиатурный маршрут»
в статьях являются планом ручной проверки; они не выданы за наблюдённый
результат.
Вердикт прохода: **пройден**. Факты привязаны к первичным источникам, а
свойства, зависящие от браузера, версии или вспомогательной технологии,
отделены от уже проверенной разметки.
## Проход 2. Редактура и голос M2 / 2019 — пройдено
| Ревизия | Симптом и цена в начале | Главный вопрос | Практический артефакт и ограничение |
| --- | --- | --- | --- |
| Практика | Фокус исчезает, у поля нет имени или ошибка остаётся рамкой; цена — сорванное действие и поздняя переделка формы | Как пройти один безопасный keyboard route до релиза | Форма с label, text error и планом DevTools; нет заявления о выполненном screen-reader run |
| Механизм | DOM и click-обработчик есть, но role/name/focus не доказаны; цена — хаотичные role и tabindex | Где заканчивается DOM и начинается наблюдаемая семантика браузера | Сравнение разметки, таблица слоёв и маршрут проверки; browser tree не выдан за универсальную матрицу поддержки |
| Полевой разбор | Красная ошибка не объясняет проблему и оставляет фокус на submit; цена — пользователь угадывает исправление | Как собрать контракт между валидацией, текстом, состоянием и фокусом | Одна функция состояния ошибки и последовательность ручной проверки; сеть и assistive technology не имитируются |
- Первые абзацы во всех трёх текстах содержат слова «симптом», «проблема» или
конкретный сбой и называют цену. Дальше выдержана практическая цепочка:
симптом → причина → проверка → действие → граница.
- Голос соответствует M2 / 2019: автор уверенно работает с HTML, формами,
модульным JavaScript и browser tooling, но не приписывает себе опыт
платформенной доступности, поздние SLO-практики или масштабные
организационные процессы.
- Техническая речь короткая и предметная. В ней названы label,
for, id, aria-describedby,
aria-invalid, tabindex, active element, role,
name, description и конкретные шаги проверки. Шаблонные обобщения и
обещания «универсальной доступности» удалены.
- Каждая статья содержит не менее пяти смысловых разделов, доступную таблицу
с caption/thead, figure с alt/caption, код,
упорядоченный маршрут и список первичных источников.
Вердикт прохода: **пройден**. Материалы продолжают фронтенд-ветку автора
2019 года и не маскируют проверяемые условия общими советами.
## Проход 3. Визуал и выпуск — пройдено в пределах автономного пакета
- accessibility-keyboard-route-2019.svg ведёт вертикально от
видимого фокуса через именованное поле к текстовой ошибке. Короткие подписи
и viewBox без фиксированной ширины позволяют схеме уменьшаться вместе с
контейнером статьи.
- accessibility-computed-semantics-2019.svg сопоставляет
несвязанную подпись рядом с input и семантически связанную пару label/input.
Схема показывает, что именно нужно проверить в браузере: role, name и
description, а не заявляет результат screen-reader run.
- accessibility-error-contract-2019.svg показывает одновременное
изменение текста, aria-invalid и выбранной точки фокуса после
submit. Последний блок оставляет явную границу: Tree и клавиатура —
проверка браузера; прогон со вспомогательной технологией — отдельный
эксперимент.
- Каждый SVG содержит title, desc, role="img"
и aria-labelledby. В SVG нет JavaScript, внешних URL,
foreignObject или растровых data URI. У figure в статьях есть
самостоятельные alt и подписи.
- Основной редактор отдельно отрисовал три SVG через Sharp в PNG шириной
375 px. В первом варианте нижняя подпись схемы error-contract была слишком
длинной для узкого экрана; её заменили короткой двухстрочной формулировкой.
Повторный рендер трёх схем не показал обрезания, наложения или
горизонтального выхода. Это проверка статичных схем, а не browser-run.
- После подключения registry строгий аудит подтвердил для всех трёх slug
объём, figure, table и code example; production build сгенерировал 374
статические страницы. Реальный keyboard-route и screen-reader прогон на
выбранной форме остаются отдельным ручным сценарием и не заявлены как
выполненные.
### Фактические проверки
node --check web/scripts/upgrade-2019-09.mjs
cd web && npm run audit:draft -- scripts/upgrade-2019-09.mjs
xmllint --noout \
web/public/assets/editorial/2019/accessibility-keyboard-route-2019.svg \
web/public/assets/editorial/2019/accessibility-computed-semantics-2019.svg \
web/public/assets/editorial/2019/accessibility-error-contract-2019.svg
Результат финального запуска 31 июля 2026 года:
| Проверка | Результат |
| --- | --- |
| node --check | PASS, синтаксис import-safe модуля корректен |
| --print-revisions | PASS, stdout содержит только JSON и совпадает с export из трёх revision |
| npm run audit:draft -- scripts/upgrade-2019-09.mjs | PASS, все три текста в пределах 5 000–15 000 знаков основного тела |
| xmllint --noout для трёх SVG | PASS, XML корректен |
| Strict audit после подключения registry | PASS: 10 052 / 9 251 / 10 075 знаков, по одному figure, table и code example |
| npm run build | PASS, code 0, 374 статические страницы |
| Scope/self-review | PASS: нет date/author в revision, скриптов в SVG или перезаписи articles.json |
Выпусковой вердикт: **тройное ревью пройдено, пакет принят к публикации**.
articles.json не менялся; registry заменяет только редакционные
поля по стабильному slug. Проверка поведения в выбранном браузере и со
вспомогательной технологией не подменяется этой публикационной проверкой: её
нужно выполнить на реальной форме отдельно.