Дайджесты новостей
Складной смартфон в позе книги с адаптивным двухэкранным интерфейсом на рабочем столе разработчика рядом с блокнотом схем.

Safari 27.1 и складные экраны: полное руководство по Device Posture и Viewport Segments API

Появление складных мобильных устройств долгое время казалось веб-разработчикам нишевой экзотикой. Большинство фронтендеров привыкли относиться к смартфонам с гибкими дисплеями как к обычным планшетам: казалось, сработает стандартный медиа-запрос @media (min-width: 768px), и макет сам перестроится в две колонки.

Однако этот оптимизм разбивается о физическую реальность складного экрана. Посередине дисплея проходит физический сгиб или шарнирная петля. Если сайт свёрстан без учёта этой границы, линия сгиба безжалостно разрезает текст, ломает заголовки и делит кликабельные кнопки пополам. Читать такой сайт становится неудобно.

С выходом складного смартфона iPhone Duo компания Apple представила обновление браузера Safari 27.1 на базе движка WebKit, о котором подробно рассказано в статье WebKit Features for Safari 27.1. В этом релизе команда реализовала предварительную поддержку двух ключевых спецификаций консорциума W3C: стандарта определения позы устройства W3C Device Posture API и механизма сегментации области просмотра Viewport Segments API.

Веб-платформа получила стандартизированный математический аппарат для создания двухэкранных интерфейсов без костылей и хаков. Разберём, как устроены эти технологии под капотом, как с ними работать в CSS и JavaScript и почему эпоха парсинга строк User-Agent окончательно ушла в прошлое.

Геометрия двух экранов: анатомия вьюпортов и физических поз iPhone Duo

Аппаратная платформа iPhone Duo включает два независимых дисплея:

  1. Внешний экран (Cover Display): работает, когда устройство полностью сложено. Это компактный экран смартфона, оптимизированный под управление одной рукой. В Safari 27.1 адресная строка и панель вкладок расположены внизу экрана.
  2. Внутренний большой экран (Inner Dual Display): открывается при распахивании устройства. Панель вкладок браузера автоматически переезжает наверх, а при начале скролла компактно сжимается. В горизонтальной ориентации поддерживается режим Split View, позволяющий открыть два независимых окна браузера бок о бок.

В таблице ниже собраны физические размеры области просмотра (Viewport) в Safari 27.1 в CSS-пикселях:

Режим и ориентация устройстваШирина (Width, px)Малая высота (SVH, px)Большая высота (LVH, px)Особенности компоновки
Внешний экран, портрет382580618Компактный мобильный экран, боковые контролы
Внешний экран, ландшафт594368406Сверхкомпактная высота, свернутая строка URL
Внутренний экран, портрет669867902Близок по пропорциям к планшету iPad mini
Внутренний экран, ландшафт951585620Широкий двухэкранный разворот со сгибом по центру
Внутренний экран, два окна бок о бок385571609Каждая вкладка получает независимый мобильный вьюпорт

Складной форм-фактор вводит понятие физических поз устройства (Device Poses):

  • Continuous (Плоская поза): дисплей раскрыт на 180 градусов (единая плоскость) либо устройство закрыто и активен внешний экран. Шарнир не разделяет контент на независимые зоны.
  • Book Pose (Поза книги): экран полусогнут по вертикальной оси под углом от 90 до 150 градусов. Пользователь держит телефон двумя руками, как раскрытую книгу.
  • Laptop Pose (Поза ноутбука): устройство согнуто по горизонтальной оси под прямым углом и стоит на столе. Нижняя половина лежит горизонтально, а верхняя поднята вертикально перед глазами.
  • Tent Pose (Поза палатки): телефон установлен «домиком» сгибом вверх для просмотра видео.

В Safari 27.1 встроена нативная механика: при открытии веб-документа PDF и сгибании телефона в позу книги (Book pose) Safari автоматически переключает отображение на двухстраничный разворот. При распрямлении в плоское положение страницы мгновенно выстраиваются в единую вертикальную ленту.

Device Posture API: как веб узнаёт о физическом сгибе устройства

Спецификация W3C Device Posture API отвечает на вопрос, в каком физическом состоянии находится экран прямо сейчас.

Стандарт оперирует двумя каноническими состояниями:

  • continuous: поверхность экрана плоская, шарнир не создаёт излома плоскости.
  • folded: экран согнут под углом, образуя две наклонённые плоскости (поза книги или ноутбука).

В стилях CSS для этого предусмотрено медиавыражение device-posture:

/* Базовый одноколоночный макет для плоского экрана */
.article-content {
  max-width: 720px;
  margin: 0 auto;
  padding: 20px;
}

/* Автоматическая перестройка в разворот при сгибании экрана */
@media (device-posture: folded) {
  .article-content {
    max-width: 100%;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 40px;
  }
}

На уровне JavaScript статус доступен через глобальный интерфейс navigator.devicePosture:

// Отслеживание физического положения устройства через JavaScript
function setupPostureListener() {
  if (!('devicePosture' in navigator)) {
    console.log('Device Posture API не поддерживается текущим браузером');
    return;
  }

  function onPostureChange() {
    const currentPosture = navigator.devicePosture.type; // 'continuous' или 'folded'
    document.body.dataset.devicePosture = currentPosture;

    if (currentPosture === 'folded') {
      enableDualScreenMode();
    } else {
      resetToDefaultView();
    }
  }

  onPostureChange();
  navigator.devicePosture.addEventListener('change', onPostureChange);
}

setupPostureListener();

Событие change срабатывает аппаратно, когда датчики угла шарнира фиксируют складывание устройства.

Включение флагов разработчика

В Safari 27.1 оба стандарта находятся в статусе Developer Preview. Для тестирования откройте: Настройки → Приложения → Safari → Дополнительно → Feature Flags и включите тумблеры «Device Posture API» и «Viewport Segments API».

Viewport Segments API: координатная сетка и шесть переменных окружения env()

Спецификация Viewport Segments API описывает точную геометрию сегментов экрана по обе стороны от шарнира.

Техническая схема двухэкранной координатной сетки Viewport Segments API для Safari 27.1 с переменными env() и зазором под петлю.

Стандарт вводит два медиавыражения:

  1. @media (horizontal-viewport-segments: 2): область просмотра разделена вертикальным сгибом на два сегмента, расположенных горизонтально бок о бок (режим книги / Book pose).
  2. @media (vertical-viewport-segments: 2): область просмотра разделена горизонтальным сгибом на два сегмента, расположенных друг над другом (режим ноутбука / Laptop pose).

Для обращения к точным координатам каждого сегмента W3C расширила функцию env(), принимающую индексы x (колонка от нуля слева направо) и y (строка от нуля сверху вниз):

  • env(viewport-segment-width <x> <y>) — ширина сегмента в пикселях.
  • env(viewport-segment-height <x> <y>) — высота сегмента.
  • env(viewport-segment-top <x> <y>) — верхняя граница сегмента.
  • env(viewport-segment-bottom <x> <y>) — нижняя граница сегмента.
  • env(viewport-segment-left <x> <y>) — левая граница сегмента.
  • env(viewport-segment-right <x> <y>) — правая граница сегмента.

Для горизонтального разворота книги (horizontal-viewport-segments: 2):

  • Левая половина имеет индекс 0 0.
  • Правая половина имеет индекс 1 0.

Расстояние между правой границей левого сегмента env(viewport-segment-right 0 0) и левой границей правого env(viewport-segment-left 1 0) — это физическая ширина шарнира. Используя calc(), мы задаём зазор в CSS Grid, гарантируя, что ни один пиксель контента не попадёт под физическую петлю.

Практикум вёрстки: адаптация каталога под книгу и видеоплеера под ноутбук

Рассмотрим два реальных прикладных сценария.

Сценарий 1: Двухэкранная карточка товара интернет-магазина (Book Pose)

На обычном телефоне карточка товара открывается классической вертикальной лентой: сверху фото, под ней описание и кнопка. При раскрытии iPhone Duo в виде книги интерфейс делится: слева остаётся галерея фотографий, а справа — блок оформления заказа.

/* Базовые стили для стандартных плоских экранов */
.product-card {
  display: flex;
  flex-direction: column;
  padding: 16px;
  background: #ffffff;
}

.product-gallery {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

/* Адаптация под двухэкранный разворот */
@media (horizontal-viewport-segments: 2) {
  .product-card {
    display: grid;
    /* Колонки строго по ширине аппаратных сегментов */
    grid-template-columns: 
      env(viewport-segment-width 0 0) 
      env(viewport-segment-width 1 0);
    /* Зазор сетки точно равен ширине центрального шарнира */
    column-gap: calc(
      env(viewport-segment-left 1 0) - env(viewport-segment-right 0 0)
    );
    padding: 0;
    height: 100vh;
  }

  .product-gallery {
    grid-column: 1;
    height: env(viewport-segment-height 0 0);
    overflow-y: auto;
  }

  .product-info {
    grid-column: 2;
    height: env(viewport-segment-height 1 0);
    overflow-y: auto;
    padding: 32px;
  }
}

Браузер сам вычисляет ширину сегментов и создаёт зазор, чтобы шарнир оказался в пустом пространстве между колонками.

Сценарий 2: Видеоплеер в позе ноутбука (Laptop Pose)

Когда пользователь ставит полусогнутый телефон на стол нижней половинкой вниз, видео отображается на верхней панели, а нижняя превращается в пульт управления:

/* Поза ноутбука: горизонтальный шарнир делит экран пополам */
@media (vertical-viewport-segments: 2) and (device-posture: folded) {
  .theater-layout {
    display: grid;
    grid-template-rows: 
      env(viewport-segment-height 0 0) 
      env(viewport-segment-height 0 1);
    height: 100vh;
    background: #000000;
  }

  .theater-video-screen {
    grid-row: 1;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .theater-control-deck {
    grid-row: 2;
    background: #1c1c1e;
    padding: 24px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }
}

JavaScript-инспекция сегментов

Для программного доступа к границам используйте массив window.viewport.segments: он возвращает объекты DOMRect с координатами x, y, width и height для каждого сегмента экрана.

Прогрессивное улучшение: почему пора навсегда забыть про парсинг User-Agent

Команда WebKit в анонсе Safari 27.1 выступила с предупреждением: ни в коем случае не используйте UA-сниффинг для складных экранов!

Строка User-Agent на iPhone Duo сделана полностью идентичной стандартному Safari на обычном iPhone. Сервер не отличит iPhone Duo от iPhone 16 по заголовку браузера. Это осознанная политика Apple: веб должен оставаться единым.

Фундаментальный принцип современного веб-дизайна — Feature Detection:

  1. Прогрессивное улучшение: базовая верстка пишется как стандартный гибкий Flexbox для одной колонки. Старые браузеры покажут удобный рабочий сайт.
  2. Нативные медиа-запросы: используйте @media (horizontal-viewport-segments: 2) для активации двухэкранных сеток.
  3. Отладка в симуляторе: утилита Device Hub в Xcode 27.1 позволяет переключать позы виртуального iPhone Duo и тестировать переменные окружения без покупки устройства.

Спецификации Device Posture и Viewport Segments API дают фронтендерам надёжный, стандартизированный W3C инструмент для адаптации под складные экраны будущего.