Мета-тег viewport сообщает мобильным браузерам, какой ширины делать область раскладки страницы и с каким масштабом её открывать. Почти каждому сайту нужна ровно эта строка в <head>:
<meta name="viewport" content="width=device-width, initial-scale=1">
Без неё телефоны считают страницу десктопной, раскладывают её примерно на 980 px в ширину и уменьшают под размер экрана. Адаптивный CSS так и не получает шанса сработать.
Что происходит без мета-тега viewport
Когда появились первые смартфоны, большинство сайтов делали под десктопные экраны. Чтобы вообще их показать, мобильные браузеры притворялись, что у них «область раскладки» десктопного размера (980 px в Safari на iOS и Chrome на Android), и уменьшали масштаб, чтобы страница целиком влезла в экран. Дальше пользователи увеличивали её щипком, чтобы прочитать.
Это поведение по умолчанию до сих пор действует для любой страницы без тега viewport. На телефоне с экраном шириной 390 px такая страница:
- сообщает CSS и JavaScript ширину области просмотра около 980 px;
- никогда не попадает под медиазапросы вроде
(max-width: 600px); - показывает текст примерно в 40% от задуманного размера.
Если на телефонах сайт выглядит как крошечная десктопная страница, первым делом проверьте этот тег. Это самая частая причина из разобранных в статье почему сайт неправильно отображается на телефоне.
Что означает каждое значение
| Значение | Смысл | Рекомендуется |
|---|---|---|
width=device-width |
Задаёт ширину области раскладки равной ширине устройства в CSS-пикселях (например, 390 у многих iPhone) | Да |
initial-scale=1 |
Начальный масштаб 100%, 1 CSS-пиксель соответствует 1 аппаратно-независимому пикселю | Да |
minimum-scale |
Минимально допустимый масштаб | Нужен редко |
maximum-scale |
Максимально допустимый масштаб | Избегайте значений меньше 5 |
user-scalable=no |
Отключает масштабирование щипком | Избегайте |
width=1024 (фиксированное число) |
Принудительно задаёт фиксированную ширину раскладки | Избегайте на адаптивных сайтах |
viewport-fit=cover |
Растягивает страницу под вырез и скруглённые углы | Только с отступами safe area |
interactive-widget |
Управляет тем, как экранная клавиатура меняет размер страницы | По желанию |
Почему не стоит отключать масштабирование
user-scalable=no и maximum-scale=1 не дают людям увеличивать страницу. Для слабовидящих это затрудняет или делает невозможным чтение и противоречит требованию WCAG о возможности увеличить текст до 200%. Lighthouse отмечает это в аудите доступности.
Разработчики часто добавляют эти значения, чтобы Safari на iOS не увеличивал масштаб при фокусе на полях формы. Правильное решение — размер шрифта в полях не меньше 16 px:
input, select, textarea { font-size: 1rem; }
Современный Safari на iOS в любом случае игнорирует user-scalable=no для масштабирования щипком, так что тег вредит в основном в других браузерах.
viewport-fit=cover и безопасные зоны
На телефонах с вырезом, Dynamic Island или скруглёнными углами браузеры по умолчанию держат страницу внутри безопасного прямоугольника. viewport-fit=cover позволяет странице занять весь экран, что может понадобиться для дизайна во всю ширину. Тогда отодвигать контент от выреза и индикатора «Домой» придётся самостоятельно:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
.site-header {
padding-left: max(1rem, env(safe-area-inset-left));
padding-right: max(1rem, env(safe-area-inset-right));
}
.bottom-bar { padding-bottom: env(safe-area-inset-bottom); }
Проверяйте это в горизонтальной ориентации, где вырез оказывается сбоку.
interactive-widget и экранная клавиатура
Когда открывается клавиатура, браузеры либо уменьшают только визуальную область просмотра (так по умолчанию в Chrome и Safari), либо меняют размер всей раскладки. Новое значение interactive-widget позволяет выбрать:
resizes-visual: по умолчанию; раскладка не меняет размер, а клавиатура перекрывает её часть;resizes-content: область раскладки уменьшается, поэтому элементы с100dvhи фиксированные футеры поднимаются над клавиатурой;overlays-content: ничего не меняет размер; обрабатывайте ситуацию сами через VirtualKeyboard API.
Поддержка в браузерах различается (браузеры на Chromium её поддерживают; прежде чем полагаться на неё, проверьте текущую поддержку), так что в любом случае проверяйте формы на реальных телефонах.
Устаревшие значения, которые можно удалить
shrink-to-fit=noбыл обходным решением для iOS 9 и сейчас ни на что не влияет.target-densitydpi— старое значение Android, оно игнорируется.<meta name="HandheldFriendly">и<meta name="MobileOptimized">остались со времён кнопочных телефонов.
Как проверить тег viewport
- Откройте исходный код страницы и найдите
name="viewport". Он должен быть ровно один. - Запустите аудит Lighthouse в мобильном режиме (как это сделать): он сообщает об отсутствующем теге viewport или о теге, блокирующем масштабирование.
- Откройте страницу в мобильном виде. В режиме устройства DevTools или в Mobile View Extension, которое загружает страницу в размере реального телефона, страница без тега выглядит уменьшенной, с мелким текстом.
Частые вопросы
Какой мета-тег viewport правильный?
<meta name="viewport" content="width=device-width, initial-scale=1">. Добавляйте viewport-fit=cover, только если делаете полноэкранную вёрстку и обрабатываете безопасные зоны.
Нужен ли мета-тег viewport для адаптивной вёрстки?
Да. Без него мобильные браузеры раскладывают страницы примерно на 980 px в ширину, и мобильные медиазапросы никогда не срабатывают.
Плохо ли использовать user-scalable=no?
Да, с точки зрения доступности. Он не даёт пользователям увеличивать текст. Нежелательное увеличение на полях формы лучше исправить размером шрифта 16 px в полях ввода.