Современные сайты должны одинаково хорошо смотреться и на больших мониторах, и на планшетах, и на телефонах. Это называется адаптивный дизайн — когда страница сама подстраивается под размер экрана. Чтобы сайт знал, какого размера экран у пользователя, в CSS добавили медиазапросы. Они выясняют размеры экрана и могут управлять тем, как отображать разные блоки при разной высоте или ширине браузера. Рассказываем, как ими пользоваться.
Что такое медиазапросы
Медиазапросы — это наборы правил, которые задают разные аспекты вёрстки в зависимости от размеров и свойств экрана браузера. Они появились в CSS3 в 2012 году, а сегодня их поддерживают все современные браузеры.
В медиазапросах прописывают условия, при соблюдении которых выполняются определённые требования к стилю. Например, нам нужно сделать так, чтобы на экранах шириной до 500 пикселей верхнее меню превращалось в три точки в углу, а на больших мониторах — растягивалось на всю ширину. Или чтобы в мобильной версии сайта шрифт становился чуть больше, а также менялись отступы и фон. Всё это можно сделать с помощью медиазапросов.
Если упростить, всё работает так:
- Медиазапрос смотрит на условие, которое прописал разработчик, и проверяет, выполняется оно или нет. Например, ширина экрана меньше 500 пикселей.
- Если условие выполняется — медиазапрос делает то, что написано внутри него: меняет шрифты, отступы и фон.
- Если не выполняется — не происходит ничего. Но может сработать условие другого медиазапроса, и тогда сработает уже он.
Медиазапросов на странице может быть сколько угодно, главное, чтобы разработчик понимал, какой из них за что отвечает.
Синтаксис медиазапросов
Все медиазапросы делаются по такому шаблону:
@media (условие) {
}
Условие может быть любым связанным с экраном, например:
- размер экрана меньше или больше определённого значения в пикселях;
- портретная или ландшафтная ориентация устройства;
- включена светлая или тёмная тема на устройстве;
- плотность пикселей;
- страница развёрнута на полный экран или нет;
- соотношение высоты и ширины экрана;
- частота обновления кадров и так далее.
Теперь пример. Допустим, у нас есть обычная страница, которая отображается как есть независимо от характеристик экрана. Возьмём пару абзацев из статьи про поломку умного дома Xiaomi и сделаем простой HTML-файл:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Медиазапросы</title>
</head>
<body>
<h1>Умные устройства Xiaomi перестали работать. Почему это произошло и что делать?</h1>
<p>Эта статья выходит 5 октября 2023 года, а начиная с вечера накануне и до сегодняшнего утра не работали все умные устройства Xiaomi — лампы, пылесосы, датчики, часы и приложения умного дома. На момент публикации всё снова работает как обычно, но сам факт такой поломки — это хороший повод поговорить о том, в чём самая большая проблема умных домов и подобных устройств и можно ли её решить.</p>
<h2>Что такое умный дом</h2>
<p>Умный дом — это общее название для сети устройств, которые занимаются автоматизацией бытовых штук. Смысл умного дома в том, чтобы обеспечить пользователям комфорт и безопасность. Например, умный дом умеет:</p>
<li>включать и выключать свет в разных комнатах по расписанию или когда в них заходят;</li>
<li>подстраивать уровень освещённости под время дня или ночи;</li>
<li>регулировать декоративную подсветку;</li>
<li>открывать и закрывать шторы;</li>
<li>проветривать дом, когда в нём станет слишком душно или когда в нём упадёт концентрация свежего воздуха;</li>
<li>включать кондиционер или отопление;</li>
<li>открывать и закрывать двери, в том числе и входную, а если вы в США — то и гаражную;</li>
<li>распознавать лица и подстраивать умные приборы в комнате или в доме под конкретного человека;</li>
<li>вызывать полицию, если сработает датчик проникновения или разбитого стекла;</li>
<li>записывать всё, что происходит внутри и снаружи;</li>
<li>напоминать о том, что в холодильнике заканчиваются продукты;</li>
<li>варить кофе с утра;</li>
<li>делать уборку роботами-пылесосами.</li>
<p>Сила умного дома в том, что все устройства работают в связке и подчиняются общим алгоритмам.</p>
</body>
</html>
Теперь откроем эту страницу на телефоне с шириной экрана 700 пикселей:
Такое читать уже не очень удобно — шрифт слишком маленький и не хватает отступов по краям экрана. Чтобы сделать чтение более комфортным, добавим в шапку сайта блок со стилями, где пропишем такой медиазапрос:
Если ширина экрана 720 пикселей или меньше, то увеличь отступы, шрифт и сделай его без засечек (Arial)
Для этого добавим такой код и для наглядности сделаем его бледно-жёлтым, чтобы сразу видеть, что медиазапрос сработал:
<!-- добавляем медиазапрос в стили -->
<style type="text/css">
/* проверяем максимальную ширину экрана */
@media (max-width: 720px) {
/* указываем, как оформлять абзацы в таком случае */
p {
/* увеличиваем шрифт */
font-size : 18px;
/* меняем его внешний вид */
font-family: Arial;
/* увеличиваем межстрочное расстояние */
line-height: 24px;
}
/* указываем, что делать со всей страницей */
body{
/* добавляем отступы */
margin: 40px;
/* меняем цвет фона */
background: lightyellow;
}
};
</style>
Обновляем страницу и видим результат — браузер проверил, какой ширины окно, увидел, что оно меньше, чем указано в запросе, и применил стили оттуда. Если подвигать границу ширины браузера, можно увидеть, как при минимальном размере начинает работать медиазапрос, который меняет оформление страницы.
Что можно проверять в медиазапросах
В медиазапросах можно проверять два типа условий:
- тип устройства;
- медиафункции, то есть технические характеристики.
Существуют четыре типа устройств:
- all — любые;
- screen — с экранами;
- print — в режиме предварительного просмотра страницы перед печатью;
- speech — программы чтения с экрана.
Медиазапросы со временем развиваются, и с каждой новой версией появляются новые возможности. Версии запросов обозначаются уровнями — Level 1, Level 2 и так далее. Почти все современные браузеры поддерживают современные Level 3 и Level 4, а Level 5 пока что в разработке.
Максимальные и минимальные значения, которые можно проверить:
width | Ширина окна браузера |
height | Высота окна браузера |
aspect-ratio | Соотношение ширины и высоты браузера |
resolution | Плотность пикселей на экране |
color | Количество битов на цвет на цветном экране |
monochrome | Количество битов на цвет на монохромном экране |
color-index | Количество цветов, которые может отображать устройство |
Конкретные свойства окна, браузера или экрана, которые можно проверить в медиазапросах:
orientation | Ориентация устройства: landscape или portrait |
display-mode | Режим отображения веб-приложения: fullscreen, standalone, minimal-ui или browser |
grid | Сеточный ли экран: 0 (нет) или 1 (да) |
dynamic-range | Сочетание уровня яркости, контрастности и глубины цвета на устройстве: standard или high |
update | Частота обновления экрана: none, slow или fast |
overflow-block | Обработка содержимого, переполненного по оси блока: none, scroll, optional-paged или paged |
overflow-inline | Обработка содержимого, переполненного по встроенной оси: none или scroll |
any-hover | Возможность наводить курсор на объекты: none или hover |
pointer | Наличие указывающего устройства ввода и точность основного устройства: none, coarse или fine |
any-pointer | Наличие указывающего устройства ввода и точность любого устройства: none, coarse или fine |
Составные медиазапросы
В медиазапросах можно проверять сразу не одно, а несколько значений. Например, можно указать, что если максимальная ширина окна 1000 пикселей и устройство находится в портретной ориентации, то меняем фон на чёрный. Для этого каждое условие берут в скобки и между ними ставят логический оператор — and
, or
или not
.
Оператор and
значит, что стиль будет применён, если выполнены оба условия сразу. Например:
<style type="text/css">
/* Стиль будет применён, если высота более 720px и менее 1024px */
@media (min-height: 720px) and (max-height: 1024px) {
}
Оператор or
значит, что стиль сработает, если выполнено хотя бы одно условие:
<style type="text/css">
/* Стиль будет применён, если режим отображения — минимальный пользовательский интерфейс или браузер */
@media (display-mode: minimal-ui) or (display-mode: browser) {
}
</style>
Оператор not
говорит, что стиль сработает, если условие не выполнено:
<style type="text/css">
/* Стиль будет применён, если на устройстве включён режим HDR */
@media not dynamic-range: high {
}
</style>
В одной команде можно использовать несколько логических операторов, группируя при этом общие условия своими скобками:
<style type="text/css">
/* Стиль будет применён, если на устройстве включён режим HDR и высота экрана между 720 px и 1024 px — ИЛИ если у устройства портретная ориентация*/
@@media dynamic-range: high and (((min-height: 720 px) and (max-height: 1024 px)) or (orientation: portrait)) {
}
</style>
Где это применяется
На медиазапросах работает большинство современных сайтов. В основе самого простого движка для адаптивной вёрстки — Bootstrap — тоже лежат медиазапросы, только они скрыты внутри движка.
Основное преимущество медиазапросов в том, что разработчик может полностью контролировать то, как будет выглядеть сайт на разных устройствах с разными экранами и в разных ситуациях.
Что дальше
В следующий раз мы возьмём наш учебный сайт на Бутстрапе и попробуем сверстать его вручную — на медиазапросах и своих стилях. Подпишитесь, чтобы не пропустить выход нового проекта.