---
title: Основы отзывчивого веб-дизайна
subhead: Как создавать сайты, отвечающие потребностям и возможностям устройства, на котором они просматриваются.
description: |2-

  Как создавать сайты, отвечающие потребностям и возможностям устройства, на котором они просматриваются.
date: 2019-02-12
updated: 2020-05-14
authors:
  - petelepage
  - rachelandrew
tags:
  - blog
  - css
  - layout
  - mobile
  - ux
---

{# TODO (kayce): Удалите это жестко запрограммированное оглавление, как только появится #1983. #}

- [Установите область просмотра](#viewport).
- [Масштабируйте контент в соответствии с размером области просмотра](#size-content).
- [Используйте медиа-запросы CSS для создания отзывчивого макета](#media-queries).
- [Выбирайте точки останова правильно](#breakpoints).
- [Просматривайте точки останова медиа-запросов в Chrome DevTools](#devtools).

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

[Итан Маркотт в своей статье на сайте «A List Apart»](http://alistapart.com/article/responsive-web-design/) впервые дал определение отзывчивому веб-дизайну как такому, который отвечает потребностям пользователей и используемых ими устройств. Макет страницы меняется в зависимости от размера и возможностей устройства. Например, на телефоне пользователи будут видеть контент в виде одного столбца; а на планшете тот же контент может быть представлен уже в виде двух столбцов.

<figure>{% Video src="video/tcFciHGuF3MxnTr1y5ue01OGLBn2/8RKRFvbuoXGkOSuEArb7.mp4", autoplay=true, controls=true, loop=true, muted=true, playsinline=true %}</figure>

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

## Установите область просмотра {: #viewport}

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

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

```html/4
<!DOCTYPE html>
<html lang="en">
  <head>
    …
    <meta name="viewport" content="width=device-width, initial-scale=1">
    …
  </head>
  …

```

Значение метатега viewport `width=device-width` предписывает странице соответствовать ширине экрана в аппаратно-независимых пикселях. Пиксель, независимый от устройства (или плотности), — это представление одного пикселя, который на экране с высоким разрешением может состоять из множества физических пикселей. Это позволяет странице пересчитывать положение элементов контента в соответствии с различными размерами экрана, как на маленьком экране мобильного телефона, так и на большом мониторе.

<figure>{% Img src="image/admin/SrMBH5gokGU06S0GsjLS.png", alt="Скриншот страницы, на которой текст трудно прочитать, так как он сильно уменьшен", width="500", height="640" %} <figcaption> Пример загрузки страницы на устройстве без метатега viewport. <a href="https://without-vp-meta.glitch.me/">Посмотрите этот пример на Glitch</a>. </figcaption></figure>

<figure>{% Img src="image/admin/9NrJxt3aEv37A3E7km65.png", alt="Скриншот той же страницы с удобочитаемым размером текста.", width="500", height="888" %} <figcaption> Пример загрузки страницы на устройстве с метатегом viewport. <a href="https://with-vp-meta.glitch.me/">Посмотрите этот пример на Glitch</a>. </figcaption></figure>

[Некоторые браузеры](https://css-tricks.com/probably-use-initial-scale1/) сохраняют ширину страницы постоянной при повороте в альбомный режим и масштабируют страницу, а не разворачивают ее для заполнения экрана. Добавление значения `initial-scale=1` предписывает браузерам устанавливать соотношение 1:1 между пикселями CSS и аппаратно-независимыми пикселями, независимо от ориентации устройства, что позволяет странице использовать всю ширину альбомной ориентации.

{% Aside 'caution' %} Чтобы старые браузеры могли правильно анализировать атрибуты, используйте запятую для разделения атрибутов. {% endAside %}

Чтобы автоматизировать анализ правильности использования метатега viewport в HTML-документах, воспользуйтесь проверкой Lighthouse, которая анализирует, [используются ли в теге `<meta name="viewport">` значения `width` или `initial-scale`](https://developer.chrome.com/docs/lighthouse/pwa/viewport/).

### Обеспечьте доступность области просмотра {: #available-viewport}

Помимо установки `initial-scale` , вы также можете установить следующие атрибуты области просмотра:

- `minimum-scale`
- `maximum-scale`
- `user-scalable`

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

## Масштабируйте контент в соответствии с размером области просмотра {: #size-content}

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

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

Чтобы автоматизировать обнаружение контента, выходящего за рамки области просмотра, воспользуйтесь проверкой Lighthouse [«Размер контента не соответствует размеру области просмотра»](https://developer.chrome.com/docs/lighthouse/pwa/content-width/).

### Изображения {: #images}

Изображение имеет фиксированные размеры, и если они превышают размеры области просмотра, то это приводит к появлению полосы прокрутки. Обычный способ решения этой проблемы — задать свойству `max-width` значение `100%` для всех изображений. Если размер области просмотра будет меньше изображения, изображение уменьшится до размера области просмотра. Однако так как именно свойство `max-width` равно `100%`, а не `width`, изображение не будет растягиваться больше своего естественного размера. Как правило, лучше добавить в таблицу стилей следующий код, чтобы не иметь проблем с полосой прокрутки у неправильно масштабированных изображений.

```css
img {
  max-width: 100%;
  display: block;
}
```

#### Добавьте размеры изображения в элемент img {: #image-sizes}

При использовании `max-width: 100%` вы переопределяете естественные размеры изображения, однако вам всё равно следует использовать атрибуты `width` и `height` в теге `<img>`. Это связано с тем, что современные браузеры применяют эти сведения, чтобы зарезервировать место для изображения перед его загрузкой, чтобы избежать [смещения макета](/optimize-cls/) при загрузке контента.

### Макет {: #layout}

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

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

<figure>{% Img src="image/admin/exFCZNQLUveUnpMFjvcj.jpg", alt="Скриншот макета из двух столбцов, большая часть второго столбца выходит за пределы области просмотра", width="800", height="504" %} <figcaption> Плавающий макет с использованием пикселей. <a href="https://layout-floats-px.glitch.me/"> Посмотрите этот пример на Glitch</a>. </figcaption></figure>

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

{% Glitch {id: 'layout-floats-percent', путь: 'README.md'}%}

Современные методы CSS-верстки, такие как Flexbox, Grid Layout и Multicol, значительно упрощают создание этих гибких сеток.

#### Flexbox {: #flexbox}

Этот метод макета идеален, когда у вас есть набор элементов разного размера, и вы хотите, чтобы они удобно размещались в строке или строках, при этом меньшие элементы занимали меньше места, а большие — больше.

```css
.items {
  display: flex;
  justify-content: space-between;
}
```

В отзывчивом дизайне Flexbox можно использовать для отображения элементов в одну строку или в несколько строк по мере уменьшения доступного пространства.

{% Glitch {id: 'responseive-flexbox', height: 220}%}

[Подробнее о Flexbox](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Flexbox).

#### Макет CSS Grid {: #grid}

Макет CSS Grid позволяет легко создавать гибкие сетки. Если рассмотреть предыдущий пример с плавающей точкой, то вместо того, чтобы создавать столбцы с помощью процентов, можно было бы использовать макет сетки и блок `fr`, который представляет собой часть доступного пространства в контейнере сетки.

```css
.container {
  display: grid;
  grid-template-columns: 1fr 3fr;
}
```

{% Glitch 'two-column-grid' %}

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

{% Glitch 'grid-as-many-as-fit' %}

[Подробнее о макете CSS Grid](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Grids).

#### Макет с несколькими столбцами {: #multicol}

Для некоторых типов макета можно использовать макет с несколькими столбцами (Multicol), который может создавать гибкое количество столбцов с помощью свойства `column-width` В демонстрации ниже видно, что столбцы добавляются, если есть место в `200 пикселей` для еще одного столбца.

{% Glitch {id: 'response-multicol', path: 'style.css'}%}

[Подробнее о Multicol](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Multiple-column_Layout).

## Используйте медиа-запросы CSS для создания отзывчивого макета {: #media-queries}

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

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

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

```html/4
<!DOCTYPE html>
<html lang="en">
  <head>
    …
    <link rel="stylesheet" href="print.css" media="print">
    …
  </head>
  …
```

В качестве альтернативы можно включить стили печати в основную таблицу стилей с помощью медиа-запроса:

```css
@media print {
  /* print styles go here */
}
```

{% Aside 'note' %} Кроме того, можно включать отдельные таблицы стилей в основной файл CSS, используя синтаксис `@import`, `@import url(print.css) print;`, однако такой подход не рекомендуется по соображениям производительности. Более подробную информацию см. в разделе [«Избегайте импорта CSS»](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/page-speed-rules-and-recommendations#avoid_css_imports). {% endAside %}

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

### Медиа-запросы на основе размера области просмотра {: #viewport-media-query}

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

- `width` (`min-width`, `max-width`)
- `height` (`min-height`, `max-height`)
- `orientation`
- `aspect-ratio`

{% Glitch {id: 'media-query-size', path: 'index.html'}%}

Все эти функции отлично поддерживаются браузерами, более подробную информацию, включая информацию о поддержке браузерами, смотрите в статьях о медиа-функциях [width](https://developer.mozilla.org/docs/Web/CSS/@media/width), [height](https://developer.mozilla.org/docs/Web/CSS/@media/height), [orientation](https://developer.mozilla.org/docs/Web/CSS/@media/orientation) и [aspect-ratio](https://developer.mozilla.org/docs/Web/CSS/@media/aspect-ratio) на MDN.

{% Aside 'note' %} В спецификацию включены тесты на `device-width` и `device-height`. Их следует избегать, так как они устарели. Тесты на `device-width` и `device-height` проверяли фактический размер окна устройства, что на практике было бесполезно, поскольку он может отличаться от области просмотра, например, в случае, когда пользователь изменил размер окна браузера. {% endAside %}

### Медиа-запросы на основе возможностей устройства {: #capacity-media-query}

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

- `hover`
- `pointer`
- `any-hover`
- `any-pointer`

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

{% Glitch 'media-query-pointer' %}

Эти новые функции хорошо поддерживаются во всех современных браузерах. Подробнее о медиа-функциях [hover](https://developer.mozilla.org/docs/Web/CSS/@media/hover), [any-hover](https://developer.mozilla.org/docs/Web/CSS/@media/any-hover), [pointer](https://developer.mozilla.org/docs/Web/CSS/@media/pointer) и [any-pointer](https://developer.mozilla.org/docs/Web/CSS/@media/any-pointer) читайте на страницах MDN.

#### Использование `any-hover` и `any-pointer`

Функции `any-hover` и `any-pointer` проверяют, есть ли у пользователя возможность навести курсор или использовать этот тип указателя, даже если это не основной способ взаимодействия с устройством. Будьте очень осторожны при их использовании. Принуждать пользователя переключаться на мышь, когда он использует сенсорный экран, не очень дружелюбно! Однако `any-hover` и `any-pointer` могут быть полезны, если важно определить тип устройства пользователя. Например, для ноутбука с сенсорным экраном и трекпадом должна существовать возможность взаимодействия с крупными и мелкими указателями, в дополнение к возможности наведения.

## Выбирайте точки останова правильно {: #breakpoints}

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

### Выберите основные точки останова, начав с малых значений, и постепенно увеличивая {: #major-breakpoints}

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

Рассмотрим пример из начала статьи: прогноз погоды. Первый шаг — сделать так, чтобы прогноз хорошо смотрелся на маленьком экране.

<figure>{% Img src="image/admin/3KPWtKzDFCwImLyHprRP.png", alt="Скриншот погодного приложения на узком мобильном экране", width="400", height="667" %} <figcaption> Приложение на узком экране. </figcaption></figure>

Второй шаг — изменять размер браузера до тех пор, пока между элементами не возникнет слишком много белого пространства, и прогноз просто перестанет хорошо смотреться. Решение несколько субъективное, но размер в `600 пикселей` — это определенно слишком широко.

<figure>{% Img src="image/admin/sh1P84rvjvviENlVFED4.png", alt="Скриншот погодного приложения с большими промежутками между элементами", width="400", height="240" %} <figcaption> Макет приложения достиг той точки, когда нужно подправить дизайн. </figcaption></figure>

Чтобы вставить точку останова при ширине `600 пикселей`, создайте два медиа-запроса в конце CSS-кода для компонента: один запрос при ширине до `600 пикселей`, а другой — более `600 пикселей`.

```css
@media (max-width: 600px) {

}

@media (min-width: 601px) {

}
```

Третий шаг — выполните рефакторинг CSS-кода. В медиа-запрос для `max-width` в `600 пискелей` добавьте CSS-код только для маленьких экранов. В медиа-запрос для `min-width` в `601 пиксель` добавьте CSS-код для больших экранов.

#### При необходимости выберите второстепенные точки останова

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

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

```css
@media (min-width: 360px) {
  body {
    font-size: 1.0em;
  }
}

@media (min-width: 500px) {
  .seven-day-fc .temp-low,
  .seven-day-fc .temp-high {
    display: inline-block;
    width: 45%;
  }

  .seven-day-fc .seven-day-temp {
    margin-left: 5%;
  }

  .seven-day-fc .icon {
    width: 64px;
    height: 64px;
  }
}
```

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

```css
@media (min-width: 700px) {
  .weather-forecast {
    width: 700px;
  }
}
```

{% Glitch {id: 'responseive-прогноз', путь: 'style.css'}%}

### Оптимизируйте текст для чтения

Согласно классической теории удобочитаемости, идеальный столбец должен содержать от 70 до 80 символов в строке (примерно от 8 до 10 слов на английском языке). Таким образом, каждый раз, когда ширина текстового блока превышает 10 слов, подумайте о добавлении точки останова.

<figure>{% Img src="image/admin/C4IGJw9hbPXKnTSovEXS.jpg", alt="Скриншот страницы с текстом на мобильном устройстве", width="400", height="488" %} <figcaption> Текст, читаемый на мобильном устройстве. </figcaption></figure>

<figure>{% Img src="image/admin/rmsa1EB5FpvWV0vFIpTF.jpg", alt="Скриншот страницы текста в браузере настольного компьютера", width="800", height="377" %} <figcaption> Текст, читаемый в браузере настольного компьютера, с добавленной точкой останова для ограничения длины строки. </figcaption></figure>

Давайте подробнее рассмотрим приведенный выше пример сообщения в блоге. На маленьких экранах шрифт Roboto в `1em` отлично работает, давая 10 слов в строке, но на больших экранах требуется точка останова. В этом случае, если ширина браузера больше, чем `575 пикселей`, идеальной шириной контента будет `550 пикселей`.

```css
@media (min-width: 575px) {
  article {
    width: 550px;
    margin-left: auto;
    margin-right: auto;
  }
}
```

{% Glitch {id: 'rwd-reading', path: 'index.html'}%}

### Избегайте простого скрытия контента

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

## Просматривайте точки останова медиа-запросов в Chrome DevTools {: #devtools}

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

<figure>{% Img src="image/admin/DhaeCbVo5AmzZ0CyLtVp.png", alt="Скриншот DevTools с открытым погодным приложением и выбранной шириной 822 пикселя.", width="800", height="522" %} <figcaption> DevTools показывает, как погодное приложение выглядит при более широкой области просмотра. </figcaption></figure>

<figure>{% Img src="image/admin/35IEQnhGox93PHvbeglM.png", alt="Скриншот DevTools с открытым погодным приложением и выбранной шириной 436 пикселей.", width="800", height="521" %} <figcaption> DevTools показывает, как погодное приложение выглядит при более узкой области просмотра. </figcaption></figure>

Чтобы просмотреть свою страницу с разными точками останова:

[Откройте DevTools](https://developer.chrome.com/docs/devtools/open/) и включите [Device Mode (Режим устройства)](https://developer.chrome.com/docs/devtools/device-mode/#toggle). По умолчанию он открывается в [отзывчивом режиме.](https://developer.chrome.com/docs/devtools/device-mode/#responsive)

Для просмотра медиа-запросов откройте меню Device Mode и выберите [Show media queries (Показать медиа-запросы)](https://developer.chrome.com/docs/devtools/device-mode/#queries), чтобы отобразить точки останова в виде цветных полос над страницей.

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