---
layout: post
title: 'Новая адаптивность: веб-дизайн в мире компонентов'
subhead: Управление макетом на макро- и микроуровне в новую эпоху адаптивного веб-дизайна.
authors:
  - una
description: Медиа-характеристики, основанные на предпочтениях пользователя, контейнерные запросы, а также медиа-запросы для новых видов экранов, таких как складные экраны, открывают новую эпоху адаптивного веб-дизайна.
date: 2021-05-19
updated: 2021-05-26
hero: image/HodOHWjMnbNw56hvNASHWSgZyAf2/P5LtV5IubshVuDac8uKO.jpg
tags:
  - blog
  - css
  - layout
---

{% YouTube 'jUQ2-C5ZNRc' %}

## Адаптивный дизайн на сегодняшний день

Сегодня, говоря об адаптивном дизайне, мы чаще всего подразумеваем использование медиа-запросов для адаптации макета под экран телефона, планшета или ПК.

{% Video src="video/HodOHWjMnbNw56hvNASHWSgZyAf2/3KENjI9FiNARctTiKDak.mp4", autoplay=true, muted=true, playsinline=true, loop=true, controls=true %}

Но вскоре такое представление об адаптивном дизайне может стать таким же устаревшим, как, например, разметка страницы с использованием таблиц.

Медиа-запросы на основе области просмотра — это мощный инструмент, но их бывает недостаточно. Они не позволяют учитывать потребности пользователей или внедрять адаптивные стили в сами компоненты.

{% Aside %} В рамках данной статьи под «компонентами» подразумеваются элементы страниц, в том числе состоящие из других элементов: карточки, боковые панели и т. д. Именно из этих компонентов и строятся веб-страницы. {% endAside %}

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

К счастью, экосистема довольно быстро меняется. Стандарт CSS развивается, и новая эпоха адаптивного дизайна уже на горизонте.

Такие изменения случаются приблизительно раз в десять лет. Десять лет назад, примерно с 2010 по 2012, произошли серьезные изменения в области мобильного и адаптивного дизайна, а также появился стандарт CSS3.

<figure>{% Img src="image/HodOHWjMnbNw56hvNASHWSgZyAf2/IhVNwOMENjOT2eiIXuMg.png", alt="Хронология развития CSS-стилей", width="800", height="211" %} <figcaption> Источник: <a href="https://www.webdesignmuseum.org/web-design-history">Web Design Museum</a>. </figcaption></figure>

И вот экосистема вновь готова к серьезным изменениям, затрагивающим стандарт CSS. Инженеры Chrome и других организаций, участвующих в развитии веб-платформы, работают над прототипами и спецификациями и закладывают реализацию стандартов, которые станут началом новой эпохи адаптивного дизайна.

В число нововведений входят медиа-характеристики, основанные на предпочтениях пользователя, контейнерные запросы, а также медиа-запросы для новых видов экранов, таких как складные экраны.

{% Img src="image/HodOHWjMnbNw56hvNASHWSgZyAf2/3yqBl9BQmGEVzDQU3Ivh.png", alt="Адаптация под пользователя, контейнер и форм-фактор", width="800", height="248" %}

## Адаптация под потребности пользователя

Новые медиа-характеристики, основанные на предпочтениях пользователя, позволяют стилизовать веб-страницы в соответствии с предпочтениями и потребностями конкретного пользователя. С их помощью можно адаптировать страницу для соответствия пользовательским ожиданиям.

Вот список медиа-характеристик, основанных на предпочтениях пользователя:

- `prefers-reduced-motion`
- `prefers-contrast`
- `prefers-reduced-transparency`
- `prefers-color-scheme`
- `inverted-colors`
- …и другие.

Характеристики, основанные на предпочтениях, позволяют учитывать настройки операционной системы пользователя, чтобы сделать взаимодействие со страницей более продуманным и персонализированным, особенно для людей с ограниченными возможностями.

{% Img src="image/HodOHWjMnbNw56hvNASHWSgZyAf2/cGWnoAAwMTU7C3HOfYQl.png", alt="Настройки специальных возможностей в операционной системе", width="800", height="428" %}

### `prefers-reduced-motion`

Пользователи, которые включили в операционной системе [уменьшение движения](/prefers-reduced-motion/), хотят видеть при использовании компьютера меньше анимаций. Это значит, что при просмотре страницы их вряд ли обрадует движущаяся заставка, анимированный переворот карточек, вычурный загрузчик и другие бросающиеся в глаза анимации.

С помощью `prefers-reduced-motion` можно создавать страницы с упрощенной анимацией, при этом также показывая расширенные анимации пользователям, у которых этот параметр выключен.

{% Video src="video/HodOHWjMnbNw56hvNASHWSgZyAf2/r4z52PPvElemSUJwUCZp.mp4", autoplay=true, muted=true, playsinline=true, loop=true, controls=true %}

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

Характеристика prefers-reduced-motion не подразумевает полное отсутствие движения, поскольку движение — это неотъемлемая часть представления информации в Интернете. Вместо этого следует обеспечить базовый уровень анимации, достаточный для восприятия контента пользователями с особыми потребностями или предпочтениями, и предоставить дополнительные анимации для остальных пользователей.

### `prefers-color-scheme`

Еще одна медиа-характеристика, основанная на предпочтениях, — это [`prefers-color-scheme`](/prefers-color-scheme). Она позволяет адаптировать интерфейс с учетом цветовой темы, которую выбрал пользователь. Операционные системы как на ПК, так и на мобильных устройствах позволяют выбрать светлую, темную или автоматическую (подстраивающуюся под время суток) тему оформления.

Если для оформления страницы применяются [пользовательские CSS-свойства](https://developer.mozilla.org/docs/Web/CSS/--*), то подстановка цветовых значений — тривиальная задача. Параметры цветовой темы, такие как `backgroundColor` и `textOnPrimary`, можно с легкостью переписать, чтобы при помощи медиа-запроса динамически подстраивать их под текущую тему оформления.

{% Video src="video/HodOHWjMnbNw56hvNASHWSgZyAf2/j6Ru11BsBzCmINZDXKql.mp4", autoplay=true, muted=true, playsinline=true, loop=true, controls=true %}

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

{% Video src="video/HodOHWjMnbNw56hvNASHWSgZyAf2/ol6pVXJLT44wAkRADAcq.mp4", autoplay=true, muted=true, playsinline=true, loop=true, controls=true %}

### Дизайн темной темы оформления

При создании темной темы оформления недостаточно просто инвертировать цвета фона и текста или сделать [темную полосу прокрутки](/color-scheme/). Есть ряд моментов, которые могут быть неочевидными. Например, цвета на темном фоне в некоторых случаях следует делать менее насыщенными, чтобы избежать цветовой вибрации.

{% Img src="image/HodOHWjMnbNw56hvNASHWSgZyAf2/tWxjbJ6yYUauQoCsySSX.png", alt="Не используйте яркие, насыщенные цвета в темных темах оформления", width="698", height="640" %}

Для того чтобы создать эффект глубины и визуально «приподнять» элемент над окружением, не нужно использовать тени, так как их будет плохо видно на темном фоне. Вместо этого следует сделать фон элемента более светлым.

<figure> {% Video src="video/HodOHWjMnbNw56hvNASHWSgZyAf2/ZiasjYiaPFmJJOkxJBce.mp4", autoplay=true, muted=true, playsinline=true, loop=true, controls=true %} <figcaption> В рекомендациях <a href="https://material.io">Material Design</a> содержатся отличные советы о том, как создавать темные темы оформления. </figcaption></figure>

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

{% Img src="image/HodOHWjMnbNw56hvNASHWSgZyAf2/ZszEdn43lc4ZmcOaGKy4.webp", alt="скриншот с выступления, где изначально было показано это изображение", width="720", height="407" %}

Согласно [исследованию Android, проведенному в 2018 году](https://www.theverge.com/2018/11/8/18076502/google-dark-mode-android-battery-life), при использовании темной темы снижение энергопотребления может достигать 60%, в зависимости от яркости экрана и особенностей интерфейса. Для сравнения темной и светлой темы, в ходе которого была получена цифра в 60%, использовался экран воспроизведения YouTube с приостановленным видео; яркость экрана была установлена на 100%.

Старайтесь всегда предоставлять пользователям темную тему, когда это возможно.

## Адаптация под размер контейнера

Одно из наиболее важных нововведений CSS — это контейнерные запросы, также известные как элементные запросы. Трудно переоценить то, насколько значимым для развития экосистемы дизайна станет переход от страничного адаптивного дизайна к контейнерному.

Ниже можно ознакомиться с демонстрацией возможностей контейнерных запросов. Вы можете управлять любыми стилями элемента карточки, в том числе видимостью списка ссылок, размерами шрифтов и общей разметкой, на основании параметров родительского контейнера:

<figure> {% Video src="video/HodOHWjMnbNw56hvNASHWSgZyAf2/fvrxk5kXiif6eFX25BH5.mp4", autoplay=true, muted=true, playsinline=true, loop=true, controls=true %} <figcaption><a href="https://codepen.io/una/pen/LYbvKpK">Просмотреть демонстрацию на Codepen</a> (необходимо включить флаг в Canary).</figcaption></figure>

В примере показаны два идентичных компонента, имеющих разные размеры контейнера и размещенных внутри макета, созданного при помощи CSS Grid. Каждый компонент подстраивается под отведенное ему пространство и использует соответствующие стили.

Такая гибкость была бы невозможна при использовании только лишь медиа-запросов.

Контейнерные запросы обеспечивают намного более динамичный подход к адаптивному дизайну. Компонент карточки можно разместить в боковой панели, в разделе с hero-изображением или в сетке внутри основной части страницы; поскольку адаптивные стили привязаны к самому компоненту, его размеры определяются исходя из размеров контейнера, а не области просмотра.

Такое поведение достигается благодаря использованию правила `@container`. Оно работает аналогично медиа-запросам `@media`, но вместо параметров браузера и области просмотра позволяет запрашивать параметры родительского контейнера.

```css
.card {
  container-type: inline-size;
}

@container (max-width: 850px) {
  .links {
    display: none;
  }

  .time {
    font-size: 1.25rem;
  }

  /* ... */
}
```

Сначала установите для родительского элемента атрибут contain. Затем создайте запрос `@container` для стилизации элементов, размещенных внутри контейнера, на основании его размера, используя `min-width` или `max-width`.

Приведенный выше код использует `max-width` и устанавливает для ссылок параметр `display:none`, а также уменьшает размер шрифта элемента «.time», если контейнер имеет ширину менее `850px`.

### Карточки на основе контейнерных запросов

В этом примере интернет-магазина растений все карточки товаров, в том числе в шапке, на боковой панели недавно просмотренных товаров и в сетке со списком товаров, реализованы при помощи одного и того же компонента с идентичной разметкой.

<figure>{% Video src="video/HodOHWjMnbNw56hvNASHWSgZyAf2/D4hBchz6kaPjkgx8BCmU.mp4", autoplay=true, muted=true, playsinline=true, loop=true, controls=true %} <figcaption> <a href="https://codepen.io/una/pen/mdOgyVL">Просмотреть демонстрацию на Codepen</a> (необходимо включить флаг в Canary).</figcaption></figure>

Этот макет не содержит *ни одного* медиа-запроса и построен полностью на контейнерных запросах. Благодаря этому карточки товаров переключаются на нужный макет, чтобы заполнить отведенное для них пространство. Например, для размещения элементов в виде сетки используется макет со столбцами на основе minmax; если места становится слишком мало (т. е. достигнут минимальный размер), то происходит перекомпоновка сетки.

```css
.product {
  container-type: inline-size;
}

@container (min-width: 350px) {
  .card-container {
    padding: 0.5rem 0 0;
    display: flex;
  }

  .card-container button {
    /* ... */
  }
}

```

Если ячейка сетки имеет ширину от `350px` или выше, макет карточки получает параметр `display: flex` и становится горизонтальным, поскольку flex-direction по умолчанию имеет значение «row».

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

### Совместное использование контейнерных запросов и медиа-запросов

Контейнерные запросы имеют множество возможных применений, и одно из них — компонент календаря. При помощи контейнерных запросов можно изменять макет календарных событий и других сегментов в зависимости от доступной ширины в родительском контейнере.

<figure>{% Video src="video/HodOHWjMnbNw56hvNASHWSgZyAf2/hjV6i4PEu8wounYhHsHf.mp4", autoplay=true, muted=true, playsinline=true, loop=true, controls=true %} <figcaption><a href="https://codepen.io/una/pen/RwodQZw">Просмотреть демонстрацию на Codepen</a> (необходимо включить флаг в Canary).</figcaption></figure>

В этом примере при помощи контейнерных запросов производится компоновка и стилизация чисел и дней недели, а также задаются размеры шрифта и полей для карточек с запланированными событиями, чтобы обеспечить оптимальное использование пространства.

Затем при помощи медиа-запроса макет адаптируется для экранов небольшого размера. Этот пример демонстрирует мощь *объединения* медиа-запросов (для настройки глобальных стилей, иначе называемых макростилями) и контейнерных запросов (для настройки потомков контейнера и их микростилей).

Теперь макетом одного и того же элемента интерфейса можно управлять одновременно на макро- и микроуровне, что открывает возможности для более изящных дизайнерских решений.

### Использование контейнерных запросов сегодня

Для запуска демонстраций, приведенных выше, необходимо включить флаг в Chrome Canary. Откройте Canary, перейдите по адресу `about://flags` и включите флаг `#enable-container-queries`. Этот флаг активирует поддержку запросов `@container`, значений `inline-size` и `block-size` свойства `contain`, а также реализации Grid из LayoutNG.

### Стили с ограниченной областью действия

В качестве дополнения к контейнерным запросам рабочая группа CSS активно обсуждает реализацию [стилей с ограниченной областью действия](https://css.oddbird.net/scope/), которые позволят обеспечить определение пространств имен и предотвращение конфликтов при работе с компонентами.

<figure> {% Img src="image/HodOHWjMnbNw56hvNASHWSgZyAf2/FCHIEO4IouHOQaOJXrQD.png", alt="стили с ограниченной областью действия", width="759", height="636" %} <figcaption>Автор рисунка — <a href="https://css.oddbird.net/">Мириам Сьюзан</a>. </figcaption></figure>

Ограничение области действия позволяет избегать конфликтов имен при использовании сквозных стилей и стилей компонентов — аналогичная функциональность уже доступна в ряде фреймворков и плагинов, таких как CSS Modules. Описываемая спецификация позволит создавать для компонентов нативные инкапсулируемые стили, используя удобочитаемый CSS-код, без необходимости вносить изменения в разметку.

```css
/* @scope (<root>#) [to (<boundary>#)]? { … } */

@scope (.tabs) to (.panel) {
  :scope { /* targeting the scope root */ }
  .light-theme :scope .tab { /* contextual styles */ }
}
```

При помощи ограничения области действия можно создавать селекторы в виде «бублика», указывая условия инкапсуляции стиля, а также условия отмены его действия и возврата к более глобальному стилю.

Пример такого сценария — панель вкладок, где к самим вкладкам применяется стиль с ограниченной областью действия, а к содержимому вкладок — родительский стиль.

## Адаптация под форм-фактор

Рассуждая о новой эпохе адаптивного дизайна, нельзя не упомянуть о появлении новых форм-факторов и видов устройств (таких, как шлемы виртуальной реальности или экраны, меняющие форму), которые вскоре могут стать актуальными для сообщества веб-разработчиков.

<figure> {% Img src="image/HodOHWjMnbNw56hvNASHWSgZyAf2/OeskptFb2djUWWmX7K9y.svg", alt="Разделенные экраны", width="800", height="488" %} <figcaption>Авторы рисунка — <a href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Foldables/explainer.md">Microsoft Edge Explainers</a>. </figcaption></figure>

Складные или гибкие экраны и дизайн с поддержкой разделенных экранов — один из примеров того, как новый форм-фактор постепенно приходит в нашу жизнь. Разделение экрана — еще одна спецификация, которую мы разрабатываем с целью обеспечить поддержку устройств с таким форм-фактором.

В настоящее время существует экспериментальный [медиа-запрос](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Foldables/explainer.md) для поддержки разделенных экранов. Он используется следующим образом: `@media (spanning: <тип разделения>)`. В демонстрации показан макет в виде сетки с двумя столбцами, один из которых имеет ширину --sidebar-width (по умолчанию — 5rem), а другой — `1fr`. Когда макет просматривается на сдвоенном экране с одним вертикальным сгибом, в переменную `--sidebar-width` подставляется ширина левой части экрана из соответствующей переменной окружения.

```css
:root {
  --sidebar-width: 5rem;
}

@media (spanning: single-fold-vertical) {
  --sidebar-width: env(fold-left);
}

main {
    display: grid;
    grid-template-columns: var(--sidebar-width) 1fr;
}
```

В результате получается макет, в котором боковая панель (в данном случае — панель навигации) отображается по одну сторону от сгиба, а интерфейс приложения — по другую. Это позволяет избежать появления видимого шва поверх интерфейса.

{% Video src="video/HodOHWjMnbNw56hvNASHWSgZyAf2/Uf3RL7EhVZGK2ECiD0sT.mp4", autoplay=true, muted=true, playsinline=true, loop=true, controls=true %}

В Chrome DevTools есть функция эмуляции складных экранов, которую можно использовать для отладки и прототипирования поддержки разделенных экранов прямо в браузере.

## Заключение

Дизайн интерфейсов для экранов нестандартного формата — еще одна область применения контейнерных запросов и стилей с ограниченной областью действия: с их помощью можно изолировать стили компонентов как от макета страницы и глобальных стилей, так и от пользовательских стилей, что позволяет сделать адаптивный дизайн более гибким. Теперь вы можете комбинировать страничные медиа-запросы (для дизайна макета на макроуровне, включая поддержку разделенных экранов), контейнерные запросы (для дизайна на микроуровне) и медиа-запросы, основанные на пользовательских предпочтениях (для того, чтобы учитывать уникальные предпочтения и потребности пользователей).

{% Img src="image/HodOHWjMnbNw56hvNASHWSgZyAf2/uAJDDUDLcAsLzBf0a27b.png", alt="Круг новой адаптивности", width="800", height="442" %}

Это и есть новый адаптивный дизайн.

Он позволяет создавать макеты на макро- и микроуровне, а также учитывать пользовательские настройки и форм-фактор.

Каждое из этих изменений само по себе является значимым для веб-дизайна, но в совокупности они позволяют кардинально переосмыслить сам подход к адаптивному дизайну. Теперь адаптивный дизайн не просто позволяет учитывать размер области просмотра, а предоставляет целый набор инструментов для создания компонентов и повышенной персонализации.

Настала новая эпоха адаптивного дизайна, и вы можете сделать шаг ей навстречу.

### web.dev/learnCSS

А пока что наша команда запустила на web.dev новый, абсолютно бесплатный курс и справочник по CSS, который пригодится желающим углубить или освежить свои познания в нем. Курс доступен по ссылке: [web.dev/learnCSS](/learn/css).

Надеюсь, что вам понравился краткий обзор новой эпохи адаптивного дизайна, а также примитивов, которые сделали ее возможной. Хочется верить, что вы не меньше, чем я, воодушевлены перспективами, которые она открывает для веб-дизайна.

Поддержка стилей на основе компонентов, новых форм-факторов, а также страниц, учитывающих предпочтения пользователей, открывает перед UI-сообществом действительно обширные возможности.
