Mobile-safe дизайн
1) Принципы Mobile-safe
1. Thumb-first: зоны действия — в пределах большого пальца (нижняя навигация, FAB/primary справа снизу).
2. Touch-friendly: цели ≥ 40–48 px с полями; расстояние ≥ 8–12 px.
3. Safe-area by design: учитываем вырезы/жестовые зоны (`env(safe-area-inset-)`).
4. Скорость важнее «красоты»: LCP ≤ 2.5 c, INP ≤ 200 мс, CLS ≤ 0.1 (p75).
5. Сдержанность: минимум модалок, минимум форм, максимум автозаполнений.
6. Сети и батарея: экономный трафик, офлайн-режим, грамотные ретраи.
2) Сетка, брейкпоинты и safe-area
Брейкпоинты: ≤ 480 (мобайл), 481–768 (планшет вертикаль), 769–1024 (планшет горизонталь).
Контейнеры с max-width, гибкие карточки 1–2 колонки.
Нижние панели ≥ 56 px, запас под жестовую навигацию.
css
:root { --inset-b: env(safe-area-inset-bottom); --inset-t: env(safe-area-inset-top); }
.app { padding-bottom: calc(16px + var(--inset-b)); padding-top: calc(8px + var(--inset-t)); }
3) Текст, кнопки и интеракции
Текст: 16–18 px базовый, межстрочный 1.4–1.6, длина строки 40–70 знаков.
Кнопки: высота 44–52 px, четкий фокус/актив/disabled; иконка + текст, не только иконка.
Жесты всегда имеют альтернативу (кнопка/меню/горячая точка).
Анимации — на `transform/opacity` и уважают `prefers-reduced-motion`.
4) Формы, клавиатуры и автозаполнение
Минимизируйте поля, используйте inputmode/type и autocomplete:html
<input type="email" inputmode="email" autocomplete="email">
<input type="tel" inputmode="tel" autocomplete="tel">
<input type="number" inputmode="numeric" pattern="[0-9]">
<input type="text" autocomplete="one-time-code" />
Маски мягкие (формат показываем, но не ломаем ввод).
5) Навигация и архитектура экранов
Нижняя навигация (до 5 пунктов) + жест «назад».
До 3–5 тапов до целевого действия.
Избегайте «гамбургера» для критичных разделов; используйте табы/segmented.
Состояния UI: `loading/empty/error/success` — явные, с действиями и пояснениями.
6) Производительность и экономия
Code-split и ленивые виджеты; графики/карты грузим «по требованию».
Критические ресурсы — `preload`, остальное — `defer`/`lazy`.
Изображения AVIF/WebP + `srcset/sizes`, `loading="lazy"`.
Шрифты: 1 variable WOFF2, `font-display: swap`, preload только основного.
Кэширование и офлайн через Service Worker (PWA), `stale-while-revalidate`.
7) Сети, офлайн и ретраи
Дружелюбие к 3G/высокой задержке: лимит запросов, батчинг, jittered backoff.
Офлайн-экран с кэшем критичных данных и очередью синхронизации.
Уважайте экономию данных: Client Hints/Save-Data → легкие изображения, без авто-видео.
js const saveData = navigator.connection?.saveData;
const slow = ['slow-2g','2g'].includes(navigator.connection?.effectiveType);
if (saveData slow) enableLiteMode(); // менее тяжелые ресурсы
8) Доступность (A11y) на мобайле
Полная управляемость клавиатурой/переключателями и читабельный фокус.
Контраст ≥ WCAG AA, текст альтернатив (`alt`, `aria-label`).
Большие таргеты и пауза анимаций; жесты дублируются кнопками.
Для диаграмм — краткий текстовый резюме и таблица данных.
9) Темная тема, яркость и haptics
Темная тема — не просто инверсия; проверяйте контрасты и цветовые акценты.
Уважайте системную тему (`prefers-color-scheme`).
Haptics — дозированно (успех/ошибка), возможность отключить.
10) Приватность, разрешения и безопасность
Разрешения только в моменте ценности (камера → скан документа).
Объяснение «зачем» и fallback без разрешения.
WebAuthn/биометрия вместо пароля; менеджеры паролей поддерживаются.
Скрывайте чувствительные поля при сворачивании; таймауты с предупреждением.
11) Пуш-уведомления и фоновые задачи
Ясные ценностные сценарии, не частить; тихие часы.
One-tap unsubscribe и центр предпочтений.
Фоновые синки — малыми порциями, с ограничениями по батарее/сети.
12) Изображения, медиа и адаптивность
Placeholder с заданными размерами → нулевой CLS.
Видео по умолчанию без автоплея, с субтитрами и контролами; адаптивные битрейты.
Иконки — вектор (SVG) или спрайт; не грузите наборы по 1 МБ.
13) Сниппеты и настройки
meta viewport и акценты:html
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="theme-color" content="#11131A">
Стабилизация макета и скрытие вне экрана:
css
.card { content-visibility: auto; contain-intrinsic-size: 600px 400px; }
Режим сниженного движения:
css
@media (prefers-reduced-motion: reduce) { { animation: none!important; transition: none!important; } }
14) Тест-план (минимум)
Устройства: 1 iOS + 1 Android (малый/средний/большой экран), портрет/ландшафт.
Сети: офлайн, 3G, 4G (throttle); включить Save-Data.
Доступность: VoiceOver/TalkBack сценарии, клавиатурный проход, контраст.
Перфоманс: Web-Vitals (RUM), профилировщик; большие списки, ввод/скролл/жесты.
Устойчивость: ротация, сворачивание/возврат, убийство процесса → восстановление состояния.
Безопасность: разрешения, таймаут сессии, скрытие приватных данных, биометрия.
15) Метрики Mobile-safe
LCP / INP / CLS (p75, мобайл-только).
Time-to-Action (до первичного целевого клика).
Tap Accuracy (доля ложных тапов близких элементов).
Crash-free sessions / ANR rate (приложения/вебвью).
Data per session и Battery impact (фон/передний план).
Opt-in/opt-out пушей и engagement.
16) Анти-паттерны
Кнопки 28–32 px, плотные списки, «карты» без поля — промахи.
Текст 12–14 px на светло-сером фоне.
Модалки поверх модалок; закрытие только жестом.
Автоплей видео/анимаций на 3G/Save-Data.
Функции «только жестом», без кнопки/меню.
Неучтенные safe-area → перекрытие контента «челкой» или свайп-панелью.
17) Чек-лист экрана
- Таргеты ≥ 48 px, отступы ≥ 8–12 px
- Safe-area учтен (`viewport-fit=cover`, `env(safe-area-inset-)`)
- Текст ≥ 16 px, контраст AA, фокус/актив видимы
- Формы: корректные `type/inputmode/autocomplete`, автозаполнение работает
- LCP ≤ 2.5 c, INP ≤ 200 мс, CLS ≤ 0.1 (мобайл)
- Lazy-loading тяжелых блоков, downsampling списков
- Офлайн-экран, ретраи с backoff, Save-Data режим
- Пуши и разрешения — по требованию, с объяснением и отказом
- Темная тема и reduced-motion поддержаны
- Тесты: iOS/Android, портрет/ландшафт, 3G/офлайн, SR-проход
18) План внедрения (3 итерации)
Итерация 1 — Основы (1–2 недели):- Сетка и safe-area, таргеты 48 px, типы клавиатур/автозаполнение, базовые Web-Vitals, lazy изображений, темная тема.
- Code-split, content-visibility, офлайн + SW, Save-Data режим, ретраи/очереди, восстановление состояния, A11y-аудит.
- RUM-дашборды, анализ трафика/батареи, haptics, сценарии разрешений, улучшение списков (виртуализация), регулярные game-days мобильных сетей.
19) Мини-FAQ
Нужно ли отдельное «мобайл-меню»?
Да, но приоритет — нижняя навигация с 3–5 пунктами; гамбургер — для второстепенного.
Как уменьшить промахи по кнопкам?
Увеличьте цели до 48 px, добавьте поля вокруг, разведите по вертикали, используйте haptic на «успех/ошибку».
Офлайн обязателен?
Для критичных сценариев — да: кэш, очередь действий и честные подсказки пользователю.
Итог
Mobile-safe дизайн — это сочетание эргономики касаний, учета safe-area, производительности, доступности и устойчивости к сетям/батарее. Следуйте чек-листам, измеряйте Web-Vitals у реальных пользователей, уважайте приватность и системные настройки — и ваш интерфейс будет удобен и надежен на любом мобильном устройстве.