Основы отзывчивого веб-дизайна
Как создавать сайты, отвечающие потребностям и возможностям устройства, на котором они просматриваются.
- Установите область просмотра.
- Масштабируйте контент в соответствии с размером области просмотра.
- Используйте медиа-запросы CSS для создания отзывчивого макета.
- Выбирайте точки останова правильно.
- Просматривайте точки останова медиа-запросов в Chrome DevTools.
Всё чаще для просмотра веб-страниц используются мобильные устройства, но часто они ограничены размером дисплея и требуют иного подхода к размещению контента на экране.
Итан Маркотт в своей статье на сайте «A List Apart» впервые дал определение отзывчивому веб-дизайну как такому, который отвечает потребностям пользователей и используемых ими устройств. Макет страницы меняется в зависимости от размера и возможностей устройства. Например, на телефоне пользователи будут видеть контент в виде одного столбца; а на планшете тот же контент может быть представлен уже в виде двух столбцов.
Существует множество различных размеров экранов телефонов, фаблетов, планшетов, настольных компьютеров, игровых приставок, телевизоров и даже носимых устройств. Размеры экранов постоянно меняются, поэтому важно, чтобы ваш сайт мог адаптироваться к любому размеру экрана, как сегодня, так и в будущем. Кроме того, устройства имеют различные функции, с помощью которых мы взаимодействуем с ними. Например, некоторые из ваших посетителей будут использовать сенсорный экран. Современный отзывчивый дизайн учитывает все эти особенности, чтобы сделать сайт удобным для каждого.
Установите область просмотра #
Страницы, оптимизированные для различных устройств, должны включать метатег viewport в заголовке документа. Метатег viewport дает браузеру инструкции по управлению размерами и масштабированием страницы.
В попытке обеспечить максимальное удобство мобильные браузеры отображают страницу с шириной экрана рабочего стола (обычно около 980 пикселей
, хотя это зависит от устройства), а затем пытаются улучшить внешний вид содержимого, увеличивая размер шрифта и масштабируя контент, чтобы он соответствовал ширине экрана. Это означает, что размер шрифта может казаться непоследовательным для пользователей, которым приходится использовать двойное нажатие или уменьшать масштаб, чтобы увидеть контент и взаимодействовать с ним.
<!DOCTYPE html>
<html lang="en">
<head>
…
<meta name="viewport" content="width=device-width, initial-scale=1">
…
</head>
…
Значение метатега viewport width=device-width
предписывает странице соответствовать ширине экрана в аппаратно-независимых пикселях. Пиксель, независимый от устройства (или плотности), — это представление одного пикселя, который на экране с высоким разрешением может состоять из множества физических пикселей. Это позволяет странице пересчитывать положение элементов контента в соответствии с различными размерами экрана, как на маленьком экране мобильного телефона, так и на большом мониторе.
Некоторые браузеры сохраняют ширину страницы постоянной при повороте в альбомный режим и масштабируют страницу, а не разворачивают ее для заполнения экрана. Добавление значения initial-scale=1
предписывает браузерам устанавливать соотношение 1:1 между пикселями CSS и аппаратно-независимыми пикселями, независимо от ориентации устройства, что позволяет странице использовать всю ширину альбомной ориентации.
Чтобы автоматизировать анализ правильности использования метатега viewport в HTML-документах, воспользуйтесь проверкой Lighthouse, которая анализирует, используются ли в теге <meta name="viewport">
значения width
или initial-scale
.
Обеспечьте доступность области просмотра #
Помимо установки initial-scale
, вы также можете установить следующие атрибуты области просмотра:
minimum-scale
maximum-scale
user-scalable
При установке этих атрибутов пользователь может лишиться возможности изменять масштаб области просмотра, что может вызвать проблемы с доступностью. Поэтому мы не рекомендуем использовать эти атрибуты.
Масштабируйте контент в соответствии с размером области просмотра #
И на настольных, и на мобильных устройствах пользователи привыкли прокручивать страницы по вертикали, а не по горизонтали; необходимость применять горизонтальную прокрутку или уменьшение масштаба, чтобы увидеть всю страницу, приведет к плохим впечатлениям от сайта.
При разработке мобильного сайта с метатегом viewport можно случайно создать для страницы контент, выходящий за рамки указанной области просмотра. Например, если ширина отображаемого изображение превышает размер области просмотра, это приведет к горизонтальной прокрутке окна просмотра. Настройте контент так, чтобы он помещался в ширину области просмотра, и пользователю не приходилось прокручивать страницу по горизонтали.
Чтобы автоматизировать обнаружение контента, выходящего за рамки области просмотра, воспользуйтесь проверкой Lighthouse «Размер контента не соответствует размеру области просмотра».
Изображения #
Изображение имеет фиксированные размеры, и если они превышают размеры области просмотра, то это приводит к появлению полосы прокрутки. Обычный способ решения этой проблемы — задать свойству max-width
значение 100%
для всех изображений. Если размер области просмотра будет меньше изображения, изображение уменьшится до размера области просмотра. Однако так как именно свойство max-width
равно 100%
, а не width
, изображение не будет растягиваться больше своего естественного размера. Как правило, лучше добавить в таблицу стилей следующий код, чтобы не иметь проблем с полосой прокрутки у неправильно масштабированных изображений.
img {
max-width: 100%;
display: block;
}
Добавьте размеры изображения в элемент img #
При использовании max-width: 100%
вы переопределяете естественные размеры изображения, однако вам всё равно следует использовать атрибуты width
и height
в теге <img>
. Это связано с тем, что современные браузеры применяют эти сведения, чтобы зарезервировать место для изображения перед его загрузкой, чтобы избежать смещения макета при загрузке контента.
Макет #
Так как размеры экрана и ширина в пикселях CSS сильно различаются у разных устройств (например, у телефонов и планшетов, и даже у разных телефонов), правильный рендеринг контента не должен зависеть от определенной ширины области просмотра.
Чтобы добиться этого раньше, требовалось для элементов макета задавать значение в процентах. В приведенном ниже примере показан макет из двух столбцов с плавающими элементами, размер которых задан с помощью пикселей. Как только область просмотра становится меньше общей ширины столбцов, приходится прокручивать страницу по горизонтали, чтобы увидеть содержимое.
Используя проценты для ширины, столбцы всегда остаются в определенном процентном соотношении от контейнера. Это означает, что столбцы становятся уже, а не создают полосу прокрутки.
Современные методы CSS-верстки, такие как Flexbox, Grid Layout и Multicol, значительно упрощают создание этих гибких сеток.
Flexbox #
Этот метод макета идеален, когда у вас есть набор элементов разного размера, и вы хотите, чтобы они удобно размещались в строке или строках, при этом меньшие элементы занимали меньше места, а большие — больше.
.items {
display: flex;
justify-content: space-between;
}
В отзывчивом дизайне Flexbox можно использовать для отображения элементов в одну строку или в несколько строк по мере уменьшения доступного пространства.
Макет CSS Grid #
Макет CSS Grid позволяет легко создавать гибкие сетки. Если рассмотреть предыдущий пример с плавающей точкой, то вместо того, чтобы создавать столбцы с помощью процентов, можно было бы использовать макет сетки и блок fr
, который представляет собой часть доступного пространства в контейнере сетки.
.container {
display: grid;
grid-template-columns: 1fr 3fr;
}
Grid также можно использовать для создания обычных макетов сетки с любым количеством элементов. Количество доступных рядов будет уменьшаться по мере уменьшения размера экрана. В приведенной ниже демонстрации в строке будет столько карточек с минимальным размером 200 пикселей
, сколько в эту строку поместится.
Макет с несколькими столбцами #
Для некоторых типов макета можно использовать макет с несколькими столбцами (Multicol), который может создавать гибкое количество столбцов с помощью свойства column-width
В демонстрации ниже видно, что столбцы добавляются, если есть место в 200 пикселей
для еще одного столбца.
Используйте медиа-запросы CSS для создания отзывчивого макета #
Иногда для поддержки определенного размера экрана требуется внести в макет более значительные изменения, чем позволяют описанные выше приемы. Именно здесь и пригодятся медиа-запросы.
Медиа-запросы — это простые фильтры, которые можно применять к стилям CSS. Они позволяют легко изменять стили в зависимости от типа устройства, на котором отображается контент, или особенностей этого устройства, например, ширины, высоты, ориентации, возможности наведения курсора или использования устройства в качестве сенсорного экрана.
Для предоставления различных стилей печати, необходимо настроить тип вывода, чтобы вы могли добавить таблицу стилей со стилями печати, как показано ниже:
<!DOCTYPE html>
<html lang="en">
<head>
…
<link rel="stylesheet" href="print.css" media="print">
…
</head>
…
В качестве альтернативы можно включить стили печати в основную таблицу стилей с помощью медиа-запроса:
@media print {
/* print styles go here */
}
При отзывчивом веб-дизайне обычно запрашиваются функции устройства, например, чтобы предоставлять разные макеты для маленьких экранов и для сенсорных экранов.
Медиа-запросы на основе размера области просмотра #
Медиа-запросы позволяют создавать отзывчивую среду, в которой определенные стили применяются ко всему разнообразию экранов, от самых маленьких и до самых больших. В данном случае мы определяем размер экрана, поэтому следует проверять следующие параметры:
width
(min-width
,max-width
)height
(min-height
,max-height
)orientation
aspect-ratio
Все эти функции отлично поддерживаются браузерами, более подробную информацию, включая информацию о поддержке браузерами, смотрите в статьях о медиа-функциях width, height, orientation и aspect-ratio на MDN.
Медиа-запросы на основе возможностей устройства #
Учитывая диапазон доступных устройств, нельзя предполагать, что каждое большое устройство — это обычный настольный или портативный компьютер, или что на маленьких устройствах используются только сенсорные экраны. С некоторыми новыми дополнениями к спецификации медиа-запросов появилась возможность проверять такие характеристики, как тип указателя, используемого для взаимодействия с устройством, и возможность наведения курсора на элементы.
hover
pointer
any-hover
any-pointer
Попробуйте просмотреть эту демонстрацию на разных устройствах, например на обычном настольном компьютере, телефоне или планшете.
Эти новые функции хорошо поддерживаются во всех современных браузерах. Подробнее о медиа-функциях hover, any-hover, pointer и any-pointer читайте на страницах MDN.
Использование any-hover
и any-pointer
#
Функции any-hover
и any-pointer
проверяют, есть ли у пользователя возможность навести курсор или использовать этот тип указателя, даже если это не основной способ взаимодействия с устройством. Будьте очень осторожны при их использовании. Принуждать пользователя переключаться на мышь, когда он использует сенсорный экран, не очень дружелюбно! Однако any-hover
и any-pointer
могут быть полезны, если важно определить тип устройства пользователя. Например, для ноутбука с сенсорным экраном и трекпадом должна существовать возможность взаимодействия с крупными и мелкими указателями, в дополнение к возможности наведения.
Выбирайте точки останова правильно #
Не определяйте точки останова на основе классов устройств. Определение точек останова на основе конкретных устройств, продуктов, торговых марок или операционных систем, которые используются сегодня, усложнит дальнейшую поддержку сайта или приложения. Вместо этого сам контент должен определять, как макет адаптируется к своему контейнеру.
Выберите основные точки останова, начав с малых значений, и постепенно увеличивая #
Создавайте контент так, чтобы он сначала помещался на небольшом экране, а затем расширяйте экран до тех пор, пока не возникнет необходимость в точке останова. Это позволяет оптимизировать точки останова в зависимости от контента и поддерживать минимально возможное количество точек останова.
Рассмотрим пример из начала статьи: прогноз погоды. Первый шаг — сделать так, чтобы прогноз хорошо смотрелся на маленьком экране.
Второй шаг — изменять размер браузера до тех пор, пока между элементами не возникнет слишком много белого пространства, и прогноз просто перестанет хорошо смотреться. Решение несколько субъективное, но размер в 600 пикселей
— это определенно слишком широко.
Чтобы вставить точку останова при ширине 600 пикселей
, создайте два медиа-запроса в конце CSS-кода для компонента: один запрос при ширине до 600 пикселей
, а другой — более 600 пикселей
.
@media (max-width: 600px) {
}
@media (min-width: 601px) {
}
Третий шаг — выполните рефакторинг CSS-кода. В медиа-запрос для max-width
в 600 пискелей
добавьте CSS-код только для маленьких экранов. В медиа-запрос для min-width
в 601 пиксель
добавьте CSS-код для больших экранов.
При необходимости выберите второстепенные точки останова #
Помимо выбора основных точек останова при значительных изменениях макета, полезно также корректировать незначительные изменения. Например, между основными точками останова полезно изменить поля или отступы для элемента или увеличить размер шрифта, чтобы в макете он выглядел более естественно.
Начнем с оптимизации макета для маленьких экранов. Во-первых, увеличим шрифт, если ширина области просмотра больше 360 пикселей
. Во-вторых, при наличии достаточного места можно разместить высокую и низкую температуры на одной строчке, а не друг над другом. В-третьих, можно немного увеличить иконки погоды.
@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;
}
}
Аналогично, для больших экранов лучше ограничить максимальную ширину панели прогноза, чтобы она не занимала всю ширину экрана.
@media (min-width: 700px) {
.weather-forecast {
width: 700px;
}
}
Оптимизируйте текст для чтения #
Согласно классической теории удобочитаемости, идеальный столбец должен содержать от 70 до 80 символов в строке (примерно от 8 до 10 слов на английском языке). Таким образом, каждый раз, когда ширина текстового блока превышает 10 слов, подумайте о добавлении точки останова.
Давайте подробнее рассмотрим приведенный выше пример сообщения в блоге. На маленьких экранах шрифт Roboto в 1em
отлично работает, давая 10 слов в строке, но на больших экранах требуется точка останова. В этом случае, если ширина браузера больше, чем 575 пикселей
, идеальной шириной контента будет 550 пикселей
.
@media (min-width: 575px) {
article {
width: 550px;
margin-left: auto;
margin-right: auto;
}
}
Избегайте простого скрытия контента #
Будьте осторожны, выбирая, какое содержимое скрывать или показывать в зависимости от размера экрана. Не стоит просто скрывать содержимое только потому, что оно не помещается на экране. Размер экрана не является окончательным показателем того, что может понадобиться пользователю. Например, исключение количества пыльцы из прогноза погоды может стать серьезной проблемой для аллергиков, которым эта информация нужна, чтобы определить, безопасно ли им выходить на улицу.
Просматривайте точки останова медиа-запросов в Chrome DevTools #
После настройки точек останова для медиа-запросов вы захотите посмотреть, как выглядит ваш сайт с ними. Вы можете изменить размер окна браузера, чтобы вызвать точки останова, но в Chrome DevTools есть встроенная функция, которая позволяет легко увидеть, как выглядит страница при различных точках останова.
Чтобы просмотреть свою страницу с разными точками останова:
Откройте DevTools и включите Device Mode (Режим устройства). По умолчанию он открывается в отзывчивом режиме.
Для просмотра медиа-запросов откройте меню Device Mode и выберите Show media queries (Показать медиа-запросы), чтобы отобразить точки останова в виде цветных полос над страницей.
Щелкните одну из полос, чтобы просмотреть страницу при активном медиа-запросе. Щелкните панель правой кнопкой мыши, чтобы перейти к определению медиа-запроса.