# 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. Проверка поведения в выбранном браузере и со вспомогательной технологией не подменяется этой публикационной проверкой: её нужно выполнить на реальной форме отдельно.