Files
bare/docs/decisions/075-no-zoom-app-feel.md
T

33 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-075: Масштабирования нет, размеры шрифтов прежние
Уточняет [ADR-024](024-identity-and-ui.md): типографика из `docs/identity/brief.md` остаётся как записана, а страница перестаёт масштабироваться.
Уточнён [ADR-076](076-ios-input-accessory-is-system.md): строка сообщения снова стала `textarea`, входит в перечень элементов управления, по которым второй тап не гасится, и заменяет весь нижний отступ на 6 px только при открытой экранной клавиатуре.
## Контекст
На iPhone интерфейс жил в постоянных микрозумах. Тап по строке ввода приближал страницу: iOS Safari обязан приблизить поле мельче 16 px и обратно масштаб не возвращает. Двойной тап приближал её же, щипок — тем более. Ощущения приложения не было: страница ездила под пальцами.
Лечится это двумя способами, и они друг друга исключают. Первый — вырастить поля до 16 px: причина фокус-зума уходит, масштаб остаётся человеку. Второй — запретить масштабирование целиком. Владелец выбрал второй и отклонил первый прямо: «интерфейс должен быть как в нативном приложении, это нужно запретить», «с 16 шрифтом всё станет огромное».
Образец рядом — sixlines.ru той же команды: там `maximum-scale=1, user-scalable=no`, и на устройствах владельца страница не масштабируется.
## Решение
- Масштабирование запрещено, включая щипок. `viewport``width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover`.
- Размеры шрифтов не меняются: поля ввода остаются 14 px, остальное — как в `docs/identity/brief.md`. 16 px на полях владельцем отклонены.
- Установленное приложение объявляется двумя мета-строками сразу: `mobile-web-app-capable` и его исторический двойник `apple-mobile-web-app-capable` — iOS до сих пор смотрит на второй. Имя на экране «Домой» — `apple-mobile-web-app-title` со значением `bare`.
- `apple-mobile-web-app-status-bar-style``default`. Тема одна и светлая (ADR-024): `black-translucent` пустил бы страницу под системную полосу и написал бы её часы и значки белым по bone, то есть по светлому. `default` оставляет полосу над страницей, тёмными знаками по светлому фону.
- `touch-action: manipulation` на `html`: снимает зум по двойному тапу и задержку 300 мс, которую браузер держит, ожидая второго касания. Двойной тап — жест документа, поэтому правило на корне действует на всю страницу.
- Страховка на JS — `web/js/zoom.js`: мета-строке Safari верен не всегда. Слушатели непассивные, иначе `preventDefault` не действует. `gesturestart`, `gesturechange`, `gestureend` — события щипка, они бывают только в Safari — гасятся целиком. Второй тап подряд, ближе 350 мс и 40 px к первому, гасится, если он не по элементу управления: `preventDefault` на `touchend` уносит с собой `click`, а нажать кнопку дважды подряд — обычное дело. Прокрутка, свайпы и одиночные нажатия не трогаются вовсе.
- `overscroll-behavior: none` у страницы и `contain` у лент: резинового отскока и «потянуть для обновления» нет, прокрутка внутри лент прежняя.
- Выделение текста снято с шапки, сайдбара, кнопок и разделителей: долгое нажатие по ним показывало лупу и «копировать», а копировать там нечего. С текста сообщений, отпечатков, полей ввода и версии в подвале сайдбара (ADR-067) не снято — их копируют; версию на iPhone взять больше неоткуда, там нет ни строки адреса, ни консоли.
- `viewport-fit=cover` пускает страницу под вырез и системную полосу, поэтому отступы считаются с ней: подвал сайдбара и строка ввода добавляют к нижнему полю `env(safe-area-inset-bottom)`, страница — боковые и верхнюю вставки. Когда открыта экранная клавиатура, обычные `20px + env(safe-area-inset-bottom)` строки ввода заменяются на 6 px по ADR-076: клавиатура уже закрывает домашний индикатор. Верхняя вставка при `status-bar-style: default` нулевая и не делает ничего; она стоит на случай, когда браузер решит иначе, — строка кода против шапки, уехавшей под часы.
## Следствия
- Человек, которому нужно увеличить мелкое, средства лишается. Это сознательная цена ощущения приложения, и платят её все. Записана в `docs/ui.md`, «Доступность», рядом с контрастом и целями нажатия — чтобы её видели, а не находили.
- Safari вправе не послушаться: `user-scalable=no` он игнорирует с десятой версии, и `maximum-scale` однажды может пойти тем же путём. Тогда вернётся и фокус-зум на поле в 14 px — лечить его 16-м шрифтом отклонено, а другого лекарства нет.
- Двойной тап по кнопке не гасится страховкой: масштаба он и так не даёт, а второе нажатие важнее.
- Клиент вырос на один модуль — `web/js/zoom.js`. Он в оболочке service worker и в раскладке `docs/plan.md`.