Код
#Руководства

Медиазапросы в CSS: как настроить адаптивную вёрстку сайта

С помощью медиазапросов можно адаптировать сайт под любой экран: от смартфона до рекламных стендов.

Иллюстрация: Оля Ежак для Skillbox Media

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

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

Содержание


Что такое медиазапросы

CSS-медиазапросы (media queries) — это набор правил (запросов), которые позволяют адаптировать внешний вид веб-страницы под технические параметры устройства пользователя: ширину и высоту экрана, плотность пикселей, количество поддерживаемых цветов и так далее.

Любой медиазапрос — это условие, которое задаётся тому или иному стилю. Если условие выполняется, то стиль применяется, если нет — не применяется. Таким образом, при помощи запросов можно прописать сразу несколько стилей со своими условиями под разные ситуации. Например, для разной ширины экрана пользователя: до 320 px, от 320 px до 720 px, от 720 px до 1024 px и от 1024 px.

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

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

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

Синтаксис

Медиазапросы можно применять:

  • в правилах CSS @media и @import;
  • в тегах HTML <style>, <link>, <source> и других, имеющих атрибут media.

Ниже рассказываем о каждом из способов использования запросов.

@media

Ключевое слово @media — основной инструмент для работы медиазапросами. По сути, это обёртка для стиля: всё, что находится внутри, применяется или не применяется в зависимости от того, выполняется ли условие.

Вот как выглядит запрос @media в общем виде:

@media <условие> {
  <стиль>
}

А вот пример — запрос, который запускает разные стили, когда пользователь поворачивает экран.

@media (orientation: landscape) {
  /*Стиль применится при горизонтальной ориентации устройства*/
}
@media (orientation: portrait) {
  /*Стиль применится при портретной ориентации устройства*/
}

Как и другие правила CSS, @media можно вкладывать внутрь других правил. Например:

div {
  height: 11rem;
  background-color: blue;
  @media (max-width: 480px) {
    width: 95%
  };
  @media (min-width: 480px) {
    width: 55%
  }
}

@import

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

Вот как выглядит синтаксис запроса @import в общем виде:

@import url(<ссылка на CSS-файл>) <условие>;

При желании можно пойти и другим путём: прописать в отдельных CSS-файлах полный набор правил для каждого условия и просто подключить их с помощью конструкции @import. Тут, как говорится, на ваше усмотрение.

Минус @import — низкая производительность. Дело в том, что это правило блокирует рендеринг сайта: он просто не может отобразиться, пока браузер не загрузит все импорты. Поэтому веб-разработчики рекомендуют избегать использования этой конструкции.

Теги HTML

Также медиазапросы можно встраивать внутрь тегов HTML. Вы можете прописать несколько стилей <style>, которые будут применяться в зависимости от результата медиазапроса:

<style media="<условие>">

Если поставить тег <link> внутри <head>, можно подключить стиль из другого файла CSS, как будто вы используете ключевое слово @import. С той лишь разницей, что <link> работает быстрее, потому что не блокирует рендеринг сайта.

<head>
  <link rel="stylesheet" media="<условие>" href="<ссылка на файл CSS>">
</head>

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

Если прописать медиазапрос внутри тега <source>, то можно определять, в каких версиях вёрстки загружать медиафайл, а в каких — нет.

<source media="<условие>" srcset="<ссылка на файл>">

Таким образом можно, например, показывать картинки с разным разрешением в зависимости от устройства пользователя:

<picture>
  <source media="(max-width: 360px)" srcset="small-picture.png">
  <source media="(min-width: 360px) and (max-width: 720px)" srcset="medium-picture.png">
  <source media="(min-width: 720px)" srcset="large-picture.png">
  <img> <! Запасное изображение, нужное на случай, если ни одно из медиаусловий не выполнится; можно оставить пустым, но тег ставить обязательно -->
</picture>

Метатег viewport

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

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

Метатег viewport ставится прямо в HTML-код страницы, в раздел <header>:

<header>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</header>

Поддержка браузерами

Сейчас в веб-разработке используют две основные версии медиазапросов: Level 3 и Level 4. Оба уровня запросов поддерживаются всеми популярными современными браузерами. Существует ещё Level 5, но он пока находится на стадии разработки.

Level 3 поддерживается большим количеством старых браузеров, зато Level 4 добавляет новые медиафункции — например, частоту обновления экрана.

Разница в поддержке, впрочем, совсем небольшая и находится в пределах погрешности. Согласно данным с сайта Can I use, в июле 2023 года Level 3 поддерживают 98,29% браузеров всех интернет-пользователей, а Level 4 — 96,15%.

Какие условия можно задать в медиазапросе

Есть два вида условий, которые можно задать в медиазапросах:

  • тип устройства — отвечает за идейно разные способы потребления контента;
  • медиафункции — отвечают за технические характеристики устройства.

Типы устройств

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

  • all — все устройства;
  • screen — устройства с экранами;
  • print — устройства в режиме предварительного просмотра страницы перед печатью;
  • speech — программы чтения с экрана.

Синтаксически это оформляется так (на примере устройств с экранами):

@media screen {
  <стиль>
}

Медиафункции (характеристики)

Второй способ задать в медиазапросе условие — указать характеристики устройства или браузера: ширину окна, ориентацию устройства и так далее.

У некоторых характеристик можно задавать минимальные и максимальные значения: для этого к ним добавляются приставки min- и max-.

Медиафункции указываются в круглых скобках. Например:

@media (min-width: 480px) {
   /*Cтиль будет применяться, если ширина окна браузера больше 480 пикселей*/
}

Вот список актуальных медиафункций, которые работают в браузерах с поддержкой и Level 3, и Level 4:

ХарактеристикаОписаниеПримеры
widthШирина окна браузера. Можно использовать min и maxwidth: 720px

min-width: 35rem

max-width: 1024px
heightВысота окна браузера. Можно использовать min и maxheight: 360px

min-height: 120px

max-height: 45rem
aspect-ratioСоотношение между шириной и высотой браузера. Можно использовать min и maxaspect-ratio: 2/1

min-aspect-ratio: 8/5

max-aspect-ratio: 3/2
orientationОриентация устройстваorientation: landscape

orientation: portrait
display-modeРежим отображения веб-приложенияdisplay-mode: fullscreen

display-mode: standalone

display-mode: minimal-ui

display-mode: browser
gridПроверка, является ли экран сеточнымgrid: 0

grid: 1
resolutionПлотность пикселей на экране. Можно использовать min и maxresolution: 60dpcm

min-resolution: 75dpi

max-resolution: 300dpi
colorКоличество битов на цвет на цветном экране. Можно использовать min и maxcolor (примет любое цветное устройство).

color: 0 (примет любое не цветное устройство).

min-color: 8

max-color: 16
monochromeКоличество бит на цвет на монохромном экране. Можно использовать min и maxmonochrome (примет любое монохромное устройство).

monochrome: 0 (примет любое не монохромное устройство).

min-monochrome: 8

max-monochrome: 16
color-indexКоличество цветов, которые может отображать устройство. Можно использовать min и maxcolor-index: 2000

min-color-index: 256

max-color-index: 16000
dynamic-rangeСочетание уровня яркости, контрастности и глубины цвета на устройствеdynamic-range: standard

dynamic-range: high

А вот список медиафункций, добавленных в Level 4:

ХарактеристикаОписаниеПримеры
updateЧастота обновления экранаupdate: none

update: slow

update: fast
overflow-blockКак устройство обрабатывает содержимое, переполненное по оси блокаoverflow-block: none

overflow-block: scroll

overflow-block: optional-paged

overflow-block: paged
overflow-inlineКак устройство обрабатывает содержимое, переполненное по встроенной осиoverflow-block: none

overflow-block: scroll
any-hoverПроверка, позволяет ли любое из устройств ввода наводить курсор на объектыany-hover: none

any-hover: hover
pointerПроверка, есть ли указывающее устройство ввода. Если да, то насколько точно основное устройствоpointer: none

pointer: coarse

pointer: fine
any-pointerПроверка, есть ли указывающее устройство ввода. Если да, то насколько точно любое из устройствpointer: none

pointer: coarse

pointer: fine

Логические операторы

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

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

@media <условие> <оператор> <условие> {
  <стиль>
}

Давайте пройдёмся по этим операторам и выясним, как их применять.

and

Оператор and используется как логическое И. Запрос выполняется только в том случае, если истинно каждое из условий. Так, в примере ниже стиль применится, если ширина окна браузера больше 480 px И меньше 1024 px — то есть, где-то между этими значениями.

@media (min-width: 480px) and (max-width: 1024px) {
 }

or и ,

Оператор or используется как логическое ИЛИ. Результат медиазапроса истинен, если истинно хотя бы одно из условий. В следующем примере стиль применится, если в запросе есть указывающее устройство ввода, неточное ИЛИ точное.

@media (pointer: coarse) or (pointer: fine) {
}

В медиазапросах уровня 4 вместо оператора or можно использовать запятую:

@media (pointer: coarse), (pointer: fine) {
  /*Стиль применится, если есть указывающее устройство ввода, 
неточное или точное*/
}

not

Оператор not используется как логическое НЕ. Например:

@media not screen {
  /*Стиль применится, если у устройства нет экрана*/
}

only

Оператор only нужен, чтобы обезопасить себя от некорректной работы некоторых старых браузеров, читающих синтаксис CSS2 вместо CSS3.

Допустим, у нас есть такой запрос:

@media screen and (min-width: 480px) {
  <стиль>
}

Устаревший браузер сможет прочитать его только до первого пробела, следующего после @media screen. Соответственно, стиль он отобразит на всех устройствах с экранами, а не только на тех, у которых ширина окна больше 480 px, как нам нужно.

Если добавить оператор only, браузер дочитает только до него: @media only — и не применит стиль вовсе.

Используя оператор only, вы должны указывать тип устройства. Например:

@media only screen and (orientation: portrait) {
  /*Стиль не применится, если браузер не поддерживает 
синтаксис CSS3*/
}

Группирующие скобки

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

@media screen and (((min-width: 480 px) and (max-width: 1920 px)) or (orientation: landscape)) {
  /*Стиль применится, если у устройства есть экран, который при этом 
либо имеет ширину окна браузера от 480 px до 1920 px, либо
 ориентирован горизонтально*/
}

Резюмируем

  • Медиазапросы — это инструмент адаптивной вёрстки, который можно использовать как в CSS, так и в HTML-коде.
  • Медиазапросы позволяют запрашивать у пользователя тип и характеристики устройства. Если полученные данные соответствуют ожидаемым, то применяется оформление.
  • Если для одного стиля должно выполняться сразу несколько условий, их можно объединять с помощью логических операторов: or, запятая, and, not и only.

Изучайте IT на практике — бесплатно

Курсы за 2990 0 р.

Я не знаю, с чего начать
Научитесь: Профессия Фронтенд-разработчик Узнать больше
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована