Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Медиазапросы

Сайт открывают и на телефоне шириной 360 пикселей, и на мониторе шириной 2500. Адаптивная вёрстка подстраивает страницу под любой экран: меняет число колонок, размеры и отступы. Главный её инструмент — медиазапросы.

Тег viewport

Без этого тега телефон показывает страницу уменьшенной, как на широком экране, и медиазапросы не срабатывают. Он обязателен в <head> каждой страницы:

<meta name="viewport" content="width=device-width, initial-scale=1">
<p>Теперь ширина страницы равна ширине экрана устройства.</p>

Правило @media

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

<style>
  .box { padding: 16px; background: lightskyblue; }
 
  @media (min-width: 500px) {
    .box { background: gold; }
  }
</style>
 
<div class="box">Узкое окно — голубой, широкое — жёлтый</div>

Условие проверяет ширину окна, в котором показана страница. Окно примера по ширине равно колонке текста. Сузьте окно браузера, пока пример не станет уже 500 пикселей, — блок поголубеет. Удобнее всего — режим устройства в инструментах разработчика, о нём урок в конце курса.

min-width и max-width

УсловиеКогда срабатывает
(min-width: 600px)Ширина окна 600px и больше
(max-width: 599px)Ширина окна 599px и меньше
(600px <= width <= 900px)От 600 до 900 пикселей — новая запись диапазона

Ширины, на которых раскладка меняется, называют точками перелома (breakpoints). Их выбирают по содержимому: там, где вёрстка начинает выглядеть плохо.

Сначала телефон

Удобный подход называют mobile first: сначала пишут простые стили для узкого экрана, а потом в @media (min-width: ...) дополняют их для широкого:

<style>
  .cards { display: grid; gap: 8px; }
  .cards div { padding: 16px; background: lightskyblue; }
 
  @media (min-width: 500px) {
    .cards { grid-template-columns: 1fr 1fr 1fr; }
  }
</style>
 
<div class="cards">
  <div>Один</div><div>Два</div><div>Три</div>
</div>

На широком окне три колонки, на узком — одна. Узкая версия получилась вообще без медиазапроса.

Перестройка каркаса

Медиазапрос может поменять шаблон сетки целиком. На телефоне меню идёт над текстом, на широком экране — слева от него:

<style>
  .page { display: grid; gap: 8px; grid-template-areas: "menu" "main"; }
  .page > * { padding: 8px; background: honeydew; }
  nav { grid-area: menu; }
  main { grid-area: main; }
 
  @media (min-width: 500px) {
    .page { grid-template-columns: 120px 1fr; grid-template-areas: "menu main"; }
  }
</style>
 
<div class="page">
  <nav>Меню</nav>
  <main>Содержимое страницы</main>
</div>

Другие условия

Медиазапросы проверяют не только ширину. Условия соединяют словом and:

УсловиеЧто проверяет
(orientation: landscape)Экран повёрнут горизонтально
(hover: hover)Есть мышь, на элемент можно навести
(prefers-color-scheme: dark)В системе включена тёмная тема
(prefers-reduced-motion: reduce)Пользователь попросил меньше анимации
printСтраницу печатают: @media print

Например, @media (min-width: 500px) and (hover: hover) сработает только на широком экране с мышью.

Частая ошибка

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

<style>
  @media (min-width: 300px) {
    .box { background: gold; }
  }
  .box { padding: 16px; background: lightskyblue; }
</style>
 
<div class="box">Всегда голубой: правило ниже победило</div>

Пишите медиазапросы после основных стилей того же элемента.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.