Фраза «на телефоне нельзя продолжить» уже полезнее, чем «сделайте адаптив». В ней есть симптом, но ещё нет причины. Возможно, кнопка ушла за горизонтальный scroll, details открываются только hover, label стал пустой иконкой или код показывает другой state. Если сразу менять breakpoint, можно временно вернуть кнопку и потерять контекст перед подтверждением. Цена — ошибочное действие, повторная поддержка и release, который невозможно объяснить после жалобы.
Для разбора возьмём один учебный маршрут. Он не опирается на отчёт пользователей, конкретный телефон, heatmap или real browser trace. Мы задаём narrow/coarse/unavailable вручную, планируем summary → details → confirm и смотрим, примет ли модель hover-only. Такой артефакт не отвечает на вопрос, удобно ли людям. Зато он помогает сделать следующий шаг проверяемым: отделить факт скрытого control от предположения о причине.
Соберите наблюдение, которое можно опровергнуть
| Наблюдение | Что ещё неизвестно | Где искать | Безопасное действие |
|---|---|---|---|
| Нет видимого перехода к подтверждению | скрыт ли он CSS или не построен route | DOM, component state, route contract | не выпускать замену до явной альтернативы |
| Действие доступно только при hover | есть ли keyboard или explicit control | правила visibility и markup | добавить явный control, не удаляя контекст |
| Итог не читается без широкой таблицы | какие данные обязательны перед confirm | summary model и предметный owner | выделить краткий summary и details |
| Новый маршрут вызывает сомнение | какой откат не повторит действие | release plan и state ownership | сохранить current path до отдельной проверки |
Запись «кнопка пропала» должна содержать условия, иначе следующий инженер не сможет отличить bug от другой конфигурации. В реальном отчёте полезны URL или экран, версия приложения, browser, viewport, zoom, способ ввода, локаль, тестовые данные, начальное состояние и ожидаемый result. В этой статье мы не заполняем эти поля выдуманными значениями. Сам список — не доказательство; он только не даёт принять случайную картинку за воспроизводимый диагноз.
Минимальный разбор одной ветки
Сначала смотрим, является ли «Открыть итог» единственным переходом. Если да, hover-only уже противоречит выбранному учебному контракту. Затем выделяем information before action: заголовок, сумма или иной предметный summary — конкретный набор решает владелец операции. После этого добавляется явный button/link и отдельная ветка details. Только после появления такого маршрута имеет смысл обсуждать spacing, animation и breakpoint. Иначе косметика закрепляет ту же скрытую зависимость.
В fixture отрицательный результат возвращает hover-only-blocked-by-contract и keep-current-path. Последняя строка не означает автоматический rollback приложения. Она лишь запрещает модели объявить новый путь принятым. До выпуска команда всё равно выбирает, как выключать реализацию: флагом, отдельным route, revert commit или ограничением rollout. Этот выбор зависит от репозитория и предметной операции; его нельзя вывести из трёх строк JavaScript.
const profile = {
viewport: 'narrow',
primaryPointer: 'coarse',
hover: 'unavailable',
};
const route = planTeachingMobilePath(profile, {
id: 'confirm-order',
label: 'Подтвердить заказ',
activation: 'explicit-control',
});
console.log(route.accepted); // true
console.log(route.steps.map(({ id }) => id));
// ['summary', 'details', 'confirm']
const rejected = planTeachingMobilePath(profile, {
id: 'open-summary', label: 'Открыть итог', activation: 'hover-only',
});
console.log(rejected.reason); // hover-only-blocked-by-contract
Как не перепутать диагностику с интерпретацией
Наблюдение: control не отображается в заданном состоянии. Интерпретация: «у всех мобильных пользователей это неудобно». Первое можно проверить DOM и стилями; второе требует метода исследования. Ещё одна опасная интерпретация — «hover: none означает touch-only». Media Queries Level 4 этого не утверждает: primary capability и все доступные input mechanisms различаются. Поэтому код не должен строить бизнес-логику на такой ярлыковой классификации.
Похожая граница есть у pointer events. Наличие pointer event не гарантирует, что action достижим, и отсутствие записи в нашей fixture не означает, что браузер не работает. WCAG 2.1 помогает сформулировать, почему взаимодействие нельзя рассматривать только как mouse path, но не может заменить проверку конкретной разметки. Хороший разбор называет, какой факт подтверждён, а какой ещё является гипотезой.
Порядок исправления
- Симптом. Зафиксируйте одно состояние, в котором основной action не виден или требует hover. Сохраните реальные условия только если они действительно известны.
- Причина. Проверьте DOM, visibility rules, component state и table/overflow. Не сводите всё к ширине до просмотра владельца route.
- Проверка модели. Запустите
node web/scripts/upgrade-2022-09.mjs --verify-fixture. Она должна принять explicit route и блокировать hover-only для teaching profile. - Действие. Добавьте видимый labelled control, summary перед ним и доступный путь к details. Не прячьте отмену или ошибку в другом hover menu.
- Проверка реализации. Создайте отдельно browser/visual/keyboard сценарий с указанными условиями. Соберите результат, который другой инженер может повторить.
- Откат. Если новый путь меняет семантику или скрывает данные, верните current route; не используйте модель как основание для автоматического отката сервера.
- Последующая проверка. Если исследование или support signal покажет другой барьер, добавьте его в план работы как новый факт, а не меняйте прошлую диагностику без следа.
Что именно проверять после исправления
В изолированной реализации проверяем, что label совпадает с предметным действием, details доступны до confirm, focus не теряется при раскрытии, error не исчезает из-за нового layout и control не зависит от hover как единственного условия. Потом смотрим узкие и широкие контейнеры с фактическим текстом продукта. Таблица, сложная локаль и длинное имя могут менять layout сильнее, чем условный размер экрана. Эти результаты должны попасть в тест или отчёт, а не в комментарий «на глаз нормально».
Если нужен usability-test, ему потребуются отдельные вопросы, способ набора людей, задача без наводящей подсказки, согласованные заметки и осторожная интерпретация. У этого текста таких данных нет. Нельзя превратить fixture 9/9 в «девять пользователей успешно прошли». Это разные единицы наблюдения: assertion в модели проверяет сравнение строк и порядок массива, а исследование изучает человеческое выполнение задачи.
| Артефакт | Что он подтверждает | Что он не подтверждает |
|---|---|---|
| Учебная fixture | условный route и ветку rollback | браузерный рендер или поведение пользователя |
| Browser test | реализацию при зафиксированных условиях | потребности всех аудиторий |
| Accessibility review | конкретные критерии и разметку в scope | коммерческий эффект |
| Usability study | наблюдения выбранного метода и выборки | вечную истину о каждом устройстве |
Граница и следующий шаг
Эта диагностика не даёт готового breakpoint, не задаёт размер target и не выбирает библиотеку компонентов. В ней также нет настоящего rollback, потому что нет production state. Попытка добавить туда реальные browser facts без запуска браузера была бы подменой. Достаточно более узкого, но честного результата: отдельный основной control должен существовать в route, а hover-only на выбранном teaching profile отклоняется.
Следующий шаг — завести короткий issue с наблюдением и неизвестными полями, приложить unit fixture как contract, а затем получить visual evidence в отдельном процессе. Перед rollout запишите владельца, условие остановки и путь отката. После проверки обновите contract только если изменился сам маршрут. Так следующий разбор начнётся не со слов «на мобильном плохо», а с конкретного состояния, границы и действия.
Историческая граница сентября 2022
Фактологическая рамка ограничена тремя исторически доступными документами W3C с immutable URL: Media Queries Level 4 CRD (25.12.2021), Pointer Events Level 2 Recommendation (04.04.2019) и WCAG 2.1 Recommendation (05.06.2018). Будущие версии спецификаций, реальные product signals и device claims в тексте не используются.
Проверяемые источники
- W3C Media Queries Level 4, Candidate Recommendation Draft от 25 декабря 2021 года — датированный CRD, доступный в сентябре 2022 года. Он определяет media features pointer, hover, any-pointer и any-hover; это характеристики среды, а не тест удобства конкретного человека.
- W3C Pointer Events Level 2, Recommendation от 4 апреля 2019 года — неизменяемая Recommendation. Она задаёт модель pointer events и pointerType; статья не утверждает, что fixture создаёт browser events.
- W3C Web Content Accessibility Guidelines 2.1, Recommendation от 5 июня 2018 года — неизменяемая Recommendation. В ней есть критерии, относящиеся к pointer gestures, ориентации и reflow; соответствие продукту требует отдельной оценки, которой здесь нет.