viewport
Meta viewport управляет масштабированием и размером области просмотра на мобильных устройствах.
Зачем нужно
Без viewport мобильный браузер рендерит страницу для экрана ~980px и уменьшает её, чтобы вместить в маленький экран. Текст становится нечитаемым, пользователю приходится зумить. Meta viewport говорит браузеру: "ширина страницы = ширина экрана устройства".
Где используется
- Каждый адаптивный (responsive) сайт
- PWA (Progressive Web Apps)
- Мобильные веб-приложения
- Email-шаблоны (с ограничениями)
Предпосылки
Синтаксис
Стандартный viewport
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Это единственный вариант, который нужен в 99% случаев.
Параметры
| Параметр | Значение | Описание |
|---|---|---|
width |
device-width или число (px) |
Ширина viewport |
height |
device-height или число (px) |
Высота viewport (редко используется) |
initial-scale |
0.1 - 10 |
Начальный масштаб |
minimum-scale |
0.1 - 10 |
Минимальный масштаб |
maximum-scale |
0.1 - 10 |
Максимальный масштаб |
user-scalable |
yes / no |
Разрешить пользователю зумить |
interactive-widget |
resizes-visual / resizes-content / overlays-content |
Поведение при открытии клавиатуры |
Что значит width=device-width
Без viewport:
+--980px (виртуальный viewport)--+
| |
| Страница рендерится для |
| экрана 980px и уменьшается |
| чтобы вместиться в 375px |
| |
+--------------------------------+
|--- 375px ---|
(реальный экран)
С viewport width=device-width:
+---375px---+
| |
| Страница |
| рендерится |
| для 375px |
| |
+------------+
Что значит initial-scale=1.0
Начальный масштаб при загрузке страницы:
1.0-- без масштабирования (1:1)2.0-- двойное увеличение0.5-- уменьшение в два раза
Не блокируй масштабирование
<!-- ПЛОХО: запрет зума — нарушает доступность -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<!-- ХОРОШО: пользователь может зумить -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Запрет масштабирования (user-scalable=no или maximum-scale=1.0) -- нарушение WCAG 2.1 (критерий 1.4.4 Resize Text). Пользователи со слабым зрением не смогут увеличить текст.
Исключение: веб-приложения типа карт или графических редакторов, где зум управляется самим приложением.
Как мобильный рендеринг работает
Layout viewport vs. Visual viewport
+--- Layout viewport ---+
| |
| +-Visual viewport-+ |
| | | |
| | То, что видит | |
| | пользователь | |
| | | |
| +-----------------+ |
| |
+------------------------+
- Layout viewport -- виртуальная область, по которой рассчитывается CSS layout
- Visual viewport -- то, что физически видно на экране
width=device-width делает layout viewport равным ширине экрана устройства.
CSS-пиксели vs. физические пиксели
iPhone 14:
Физическое разрешение: 1170 x 2532 px
Device Pixel Ratio (DPR): 3
CSS viewport: 390 x 844 px (1170/3 x 2532/3)
width=device-width устанавливает viewport в CSS-пикселях, а не физических.
interactive-widget (новый параметр)
Управляет поведением страницы при появлении виртуальной клавиатуры:
<!-- Клавиатура уменьшает visual viewport (default) -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, interactive-widget=resizes-visual">
<!-- Клавиатура уменьшает и content, и visual viewport -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, interactive-widget=resizes-content">
<!-- Клавиатура перекрывает контент -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, interactive-widget=overlays-content">
Примеры
Адаптивная страница (стандарт)
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Адаптивная страница</title>
<style>
body {
margin: 0;
font-family: system-ui, sans-serif;
padding: 1rem;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
img {
max-width: 100%;
height: auto;
}
</style>
</head>
<body>
<div class="container">
<h1>Адаптивная страница</h1>
<p>Текст подстраивается под ширину экрана.</p>
<img src="photo.jpg" alt="Фото" width="800" height="600">
</div>
</body>
</html>
Проверка viewport через JavaScript
<script>
// Layout viewport ширина
console.log('Layout viewport:', document.documentElement.clientWidth);
// Visual viewport (с учётом зума)
console.log('Visual viewport:', window.visualViewport.width);
// Device Pixel Ratio
console.log('DPR:', window.devicePixelRatio);
// Реагирование на изменение visual viewport (зум, клавиатура)
window.visualViewport.addEventListener('resize', () => {
console.log('Visual viewport changed:',
window.visualViewport.width,
window.visualViewport.height
);
});
</script>
Частые ошибки
| Ошибка | Почему плохо | Как правильно |
|---|---|---|
| Нет viewport вообще | Страница не адаптируется на мобильных | Добавь стандартный viewport |
user-scalable=no |
Нарушает доступность (WCAG) | Не блокируй зум |
maximum-scale=1.0 |
Тоже блокирует зум | Не ограничивай масштаб |
width=1024 вместо device-width |
Фиксированная ширина, не адаптивно | width=device-width |
Нет initial-scale=1.0 |
Некоторые мобильные браузеры могут масштабировать неправильно | Добавь initial-scale=1.0 |
| Полагаться на viewport без responsive CSS | Viewport без media queries не делает сайт адаптивным | viewport + responsive CSS |
Практика
- Создай страницу без viewport и открой в DevTools в режиме мобильного устройства -- увидь, как страница масштабируется
- Добавь стандартный viewport и сравни
- Проверь
document.documentElement.clientWidthв консоли на desktop и мобильном - Проверь
window.devicePixelRatioна разных устройствах - Посмотри через DevTools, какой viewport используют крупные сайты
Связанные темы
- meta теги -- все meta-теги
- picture и srcset -- адаптивные изображения с учётом viewport
- Изображения -- srcset и sizes зависят от viewport