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

Практика

  1. Создай страницу без viewport и открой в DevTools в режиме мобильного устройства -- увидь, как страница масштабируется
  2. Добавь стандартный viewport и сравни
  3. Проверь document.documentElement.clientWidth в консоли на desktop и мобильном
  4. Проверь window.devicePixelRatio на разных устройствах
  5. Посмотри через DevTools, какой viewport используют крупные сайты

Связанные темы

Ресурсы