CSS медиа-запросы (media queries)

В этой статье мы подробно рассмотрим, что такое медиа-запросы, как они работают и как их правильно использовать, в том числе и для создания адаптивного дизайна. Разберём конструкции @media, которые используются в Bootstrap.
Что такое медиа-запросы
Медиа-запросы (media queries) – это правила CSS, которые позволяют управлять стилями элементов в зависимости от значений технических параметров устройств. Иными словами, это конструкции, которые позволяют определять на основании некоторых условий какие стили необходимо использовать на веб-странице, а какие нет.
Медиа-запросы появились в спецификации CSS3 и на сегодняшний день поддерживаются всеми современными браузерами (Chrome 4+, Firefox 3.5+, IE 9+, Opera 9+, Safari 4+).

Поддержка медиа-запросов в браузере IE8 осуществляется посредством подключения к странице скрипта «respond.js»:
<!-- Respond.js для IE8 (media queries) -->
<!-- Предупреждение: Respond.js не будет работать при просмотре страницы через file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
Медиа-запросы предназначены для создания адаптивных дизайнов. Адаптивный дизайн отличается от других тем, что он может «приспосабливаться» (видоизменяться) в зависимости от того, какую ширину экрана имеет устройство (браузер).
Но при создании адаптивных веб-страниц также необходимо обратить внимание на метатег viewport. Данный тег обеспечивает корректное отображение адаптивных дизайнов сайтов на экранах устройств, имеющих высокую плотность пикселей. Иными словами, он устанавливает соответствие между CSS и физическим разрешением веб-страницы.
Подключение метатега viewport к странице осуществляется так:
<meta name="viewport" content="width=device-width, initial-scale=1">
Синтаксис
Создание медиа-запроса начинается с ключевого слова @media
после которого указывается одно или несколько условий. В качестве условия можно указывать тип устройства или требования к определённой характеристике. Требование к определённой характеристике записывается в круглых скобках.
Комбинирование нескольких условий выполняется с помощью логических операторов.
После составления @media
, стили, указанные в нём, будут применяться только в том случае, когда итоговый результат вычисления условий является истинной.
Пример медиа-запроса с одним условием:
@media screen {
/* стили будут применяться, когда условие истинно */
}
Пример медиа-запроса с комбинированием нескольких условий:
@media (min-width: 992px) and (max-width: 1199.98px) { ... }
Типы устройств
В @media можно указывать определённые типы устройств:
all
– для всех;print
– для принтеров и в режиме предварительного просмотра страницы перед печатью;screen
– для устройств с экранами;speech
– для программ чтения с экрана.
Например, этот @media только для экранов:
@media screen { ... }
А здесь для экранов и принтеров:
@media screen, print { ... }
Логические операторы
Логические операторы and
, ,
(запятая), not
и only
предназначены для создания сложных медиа-запросов.
and
Оператор and
используется для объединения нескольких условий. В этом случае их результат будет истинным, когда каждое из них будет истинным.
Например, следующий @media будет применяться только при выполнении всех трёх условий (это экран, width >= 1200px и ориентация landscape):
@media screen and (min-width: 1200px) and (orientation: landscape) { ... }
, (запятая)
Применение стилей, когда необходимо лишь выполнение одного из указанных условий, достигается посредством разделения их между собой с помощью ,
(запятой).
В этом примере стили будут применяться к странице в двух случаях. Когда width >= 544px или ориентация portrait.
@media (min-width: 544px), (orientation: landscape) { ... }
not
Ключевое слово not
используется для отрицания.
При использовании not
с and
отрицание работает для всего медиа-запроса. При этом, когда указываем not
необходимо обязательно задавать тип устройства.
Например, применим стили только в том случае, когда не (экран и width >= 411px и height >= 731px).
@media not screen and (min-width: 411px) and (min-height: 731px) { ... }
При использовании not
в выражении с запятой он добавляет отрицание только для этой части.
Например, применим стили когда истинно следующее условие: не экран или не width >= 411px.
@media not screen, not (min-width: 411px) { ... }
only
Ключевое слово only
предназначено для того, чтобы браузеры, которые не поддерживают CSS3 медиа-запросы их игнорировали. В настоящее время это уже не актуально, поэтому использовать only
не нужно.
Медиа-характеристики
При составлении условия кроме типов устройств и логических операторов можно ещё задавать требования к определённым характеристикам, которые должен иметь браузер, устройство вывода, или окружение. В некоторых источниках характеристики называют медиа-функциями.
Каждая характеристика в @media должна быть заключена в круглые скобки.
При этом применяться стили указанные в @media будут также как раньше, т.е. только в том случае, когда результат вычисления всего выражения будет являться истиной.
width
Медиа-характеристика width
позволяет задать условие на равенство ширины области просмотра определённому значению.
Например, применим CSS только для viewport с шириной 320px.
@media (width: 320px) { ... }
Для определения диапазона можно использовать min-width
и max-width
.
Например, @media для ширины viewport от 576px до 1200px:
@media (min-width: 576px) and (max-width: 1199.98px) { ... }
Для ширины больше 768px:
@media (min-width: 768px) { ... }
Если нужно меньше 1400px:
@media (max-width: 1399.98px) { ... }
height
Для задания условий в отношении высоты viewport можно использовать height
, min-height
и max-height
.
Например, @media для высоты viewport больше 720px:
@media (min-height: 720px) { ... }
orientation
С помощью orientation
можно установить те или иные стили в зависимости от того, в каком режиме (альбомном или портретном) отображается сайт.
Например, в зависимости от ориентации viewport будем отображать разные картинки:
@media (orientation: landscape) {
.cover { background: url(bg-l.png) no-repeat; }
}
@media (orientation: portrait) {
.cover { background: url(bg-p.png) no-repeat; }
}
aspect-ratio
Характеристики aspect-ration
, min-aspect-ratio
и max-aspect-ratio
позволяют задавать стили в зависимости от соотношения сторон viewport.
/* Minimum aspect ratio */
@media (min-aspect-ratio: 9/16) {
.header {
background-color: #0dcaf0;
}
}
/* Maximum aspect ratio */
@media (max-aspect-ratio: 16/9) {
.header {
background: #ffc107;
}
}
/* Exact aspect ratio */
@media (aspect-ratio: 1/1) {
.header {
background: #6c757d;
}
}
resolution
Характеристики resolution
, min-resolution
и max-resolution
можно использовать, когда нужно задать стили в зависимости от плотности пикселей устройства.
Например, установим другой размер шрифта для устройств с плотностью пикселей на дюйм более 150:
/* Default */
p {
font-size: 16px;
}
/* Minimum resolution */
@media (min-resolution: 150dpi) {
p {
font-size: 14px;
}
}
Стили для печати страницы с плотностью пикселей больше 300dpi:
@media print and (min-resolution: 300dpi) { ... }
Медиа-запросы в <link> и @import
При подключении таблицы стилей можно с помощью атрибута media
установить медиа-запросы и тем самым определить условия, когда они должны использоваться.
<link rel="stylesheet" media="screen and (max-width: 991.98px)" href="/assets/mobile.css">
<link rel="stylesheet" media="screen and (min-width: 992px)" href="/assets/desktop.css">
Кроме <link>
, их также можно использовать в @import
:
@import url(mobile.css) screen and (max-width: 991.98px);
@import url(desktop.css) screen and (min-width: 992px);
Медиа-запросы для Bootstrap 3
Организация media queries в порядке возрастания классов устройств xs, sm, md и lg (по умолчанию):
/* Устройства с очень маленьким экраном (смартфоны, меньше 768px) */
/* Стили CSS (по умолчанию) - для ширины viewport <768px */
/* Устроства с маленьким экраном (планшеты, 768px и выше) */
@media (min-width: 768px) {
/* Стили для устройств с шириной viewport, находящейся в диапазоне 768px - 991px */
}
/* Устройства со средним экраном (ноутбуки и компьютеры, 992px и выше) */
@media (min-width: 992px) {
/* Стили для устройств с шириной viewport, находящейся в диапазоне 992px - 1199px */
}
/* Устройства с большим экраном (компьютеры, 1200px и выше) */
@media (min-width: 1200px) {
/* Стили для устройств с шириной viewport >1200px */
}
Вышеприведённые запросы необходимо использовать только в указанном порядке.
Для того чтобы media запросы можно было применять в какой угодной последовательности, их необходимо расширить включив в них дополнительно выражение max-width
. Это заставит их работать только в указанном диапазоне.
@media (max-width: 767px) {
/* стили для xs-устройств */
}
@media (min-width: 768px) and (max-width: 991px) {
/* стили для sm-устройств */
}
@media (min-width: 991px) and (max-width: 1199px) {
/* стили для md-устройств */
}
@media (min-width: 1200px) {
/* стили для lg-устройств */
}
Медиа-запросы для Bootstrap 4
Синтаксис медиа-запросов для Bootstrap 4, которые можно использовать только в следующем порядке (последовательного увеличения минимальной ширины viewport):
/* xs - устройства (до 576px) */
/* CSS для ширины, которая меньше 575px (включительно) */
/* sm-устройства (больше или равно 576px) */
@media (min-width: 576px) {
/* CSS для: 576px <= ширины <= 767px */
}
/* md-устройства (больше или равно 768px) */
@media (min-width: 768px) {
/* CSS для: 768px <= ширины <= 991px */
}
/* lg-устройства (больше или равно 992px) */
@media (min-width: 992px) {
/* CSS для: 992px <= ширины <= 1119px */
}
/* xl-устройства (больше или равно 1200px) */
@media (min-width: 1200px) {
/* CSS для: ширины >= 1200px */
}
Список media запросов для фреймворка Bootstrap 4, которые можно применять только в обратном порядке (в порядке убывания ширины области просмотра окна браузера):
/* xl-размер (>=1200px) */
/* CSS для >=1200px */
/* lg-размер (<=1199px) */
@media (max-width: 1199px) {
/* CSS для ширины от 992px до 1199px */
}
/* md-размер (<=991px) */
@media (max-width: 991px) {
/* CSS для ширины от 768px до 991px */
}
/* sm-размер (<=768px) */
@media (max-width: 767px) {
/* CSS для ширины от 576px до 767px */
}
/* xs-размер (<=575px) */
@media (max-width: 575px) {
/* CSS для ширины до 575px (включительно) */
}
Перечень медиа-запросов для Bootstrap 4, которые можно использовать в таблице стилей в любой последовательности:
/* xs (<=543px) */
@media (max-width: 575px) { ... }
/* sm (>=576 и <=767) */
@media (min-width: 576px) and (max-width: 767px) { ... }
/* md (>=768 и <=991) */
@media (min-width: 768px) and (max-width: 991px) { ... }
/* lg (>=992 и <=1199) */
@media (min-width: 992px) and (max-width: 1199px) { ... }
/* xl (>=1200) */
@media (min-width: 1200px) { ... }
Дополнения из Media Queries Level 4
Media Queries Level 4 – это четвертая редакция спецификации для @media
.
В ней определён новый и более простой синтаксис для создания диапазона. То есть теперь можно вместо функций min-*
и max-*
(например, min-width
и max-width
) использовать обычные математические операторы сравнения: >
, <
, >=
или <=
.
Например: @media (992px <= width < 1200px)
эквивалентно @media (min-width: 992px) and (max-width: 1199.98px)
.
Кроме этого, Media Queries Level 4 включает четыре медиа-функции, которые относятся к категории взаимодействия: pointer
, any-pointer
, hover
и any-hover
. С помощью них можно адаптировать сайты и веб-приложения для различных устройств в зависимимости от наличия у них указателя, а также от того на сколько он точен.
Функция hover
позволяет определить, может ли основное устройство ввода наводить курсор на элементы. Она принимает два значения: hover
и none
:
/* для устройств, в которых основной механизм ввода позволяет навести указатель на элемент */
@media (hover: hover) {
/* ... */
}
/* если основное устройство ввода не позволяет навести указатель на элемент */
@media (hover: none) {
/* ... */
}
Медиа-функция pointer
позволяет нам адаптировать взаимодействие с сайтом в зависимости от наличия указателя у основного механизма ввода и его точности. Она может иметь одно из трёх значений:
none
– нет указателя (например, смартфоны, взаимодействие с которыми осуществляется с помощью пальцев);coarse
– имеет указатель с ограниченной точностью (например, пульт дистанционного управления Smart TV);fine
– имеет точное указательное устройство (например: мышь, тачпад или стилус).
Пример объединения этих функций для определения устройств разных типов:
/* смартфоны, устройства с сенсорными экранами */
@media (hover: none) and (pointer: coarse) {
/* ... */
}
/* устройства с сенсорными экранами, в которых основным механизмом ввода является стилус */
@media (hover: none) and (pointer: fine) {
/* ... */
}
/* Smart TV, игровые консоли */
@media (hover: hover) and (pointer: coarse) {
/* ... */
}
/* десктопы и ноутбуки, в которых основным механизмом ввода является мышь или тачпад */
@media (hover: hover) and (pointer: fine) {
/* ... */
}
Если функции hover
и pointer
определяют на соответствие только основной механизм ввода, то any-hover
и any-pointer
– вообще любой из механизмов ввода этому условию.
Код JavaScript, учитывающий параметры устройств
Чтобы определить, соотвествует ли документ строке медиа-запроса, в JavaScript имеется функция matchMedia()
.
matchMedia()
является методом объекта window
. Его использование практически ничем не отличается от CSS медиа-запросов:
// создаём новый объект MediaQueryList, с помощью которого хотим проверить, больше ли ширина области просмотра 768px
const mediaQuery = window.matchMedia('(min-width: 768px)');
// получаем значение свойства matches, и проверяем является ли оно истинным
if (mediaQuery.matches) {
// если matches содержит true, то выведется alert
alert('Документ соотвествует медиа-запросу!');
}
Таким образом, суть работы в JavaScript сводится к передаче строки медиа-запроса в matchMedia()
, и последующей проверки свойства matches
. Это свойство доступно только для чтение и содержит логическое значение. true
– если документ соотвествует медиа-запросу, false
– в противном случае.
Например, установим цвет фона <body>
в зависимости от ширины области просмотра:
if (window.matchMedia('screen and (width >= 768px)').matches) {
document.body.style.backgroundColor = 'black';
} else {
document.body.style.backgroundColor = 'yellow';
}
Этот код выполнится один раз и при изменении размера области просмотра цвет фона <body>
не обновится.
Если нам нужно реагировать на изменения статуса медиа-запроса, то можно воспользоваться методом addListener()
. Этот метод принимает функцию обратного вызова, которая будет вызываться каждый раз при изменении статуса медиа-запроса:
// создаём медиа-запрос
const mediaQuery = window.matchMedia('screen and (width >= 768px)');
// объявляем функцию handleBreakpointChange
const handleBreakpointChange = (e) =>{
document.body.style.backgroundColor = e.matches ? 'black' : 'yellow';
}
// регистрируем функцию handleBreakpointChange в качестве обработчика события, возникающего при изменении состояния медиа-запроса
mediaQuery.addListener(handleBreakpointChange);
//
handleBreakpointChange(mediaQuery);
Теперь функция handleBreakpointChange
будет вызываться каждый раз при изменении статуса медиа-запроса.
Также очень важно отметить, что когда вы регистрируете обработчик, он изначально не срабатывает. Поэтому в примере мы вызвали функцию, которые мы используем в качестве обработчика события, вручную и передали ей медиа-запрос в качестве аргумента.
Удаления добавленного обработчика осуществляется с помощью метода removeListener()
:
Например, эту возможность можно применить для асинхронной загрузки картинок в зависимости от того какой размер viewport имеет устройство (браузер).
Метод matchMedia()
не поддерживается Internet Explorer 9 и другими старыми браузерами. Для того чтобы обеспечить эту функциональность в старых браузерах можно воспользоваться методом mq
библиотеки Modernizr.

if (Modernizr.mq('(max-width: 767px)')) {
// ... действия, если устройство соответствует указанному медиа-условию
} else {
// ... действия, если устройство не отвечает заданному медиа-условию
}
Задача: Нужно сделать рекламные блоки для мобильной и pc версии. т.е чтобы на мобильных устройствах отображалась одна реклама и на компьютерах другая.
В голову приходит что то на вроде этого варианта, но кажется этот вариант топорным, если не затруднить можете подсказать со своего взгляда, норм вариант? Либо делается более грамотно и проще?
Спасибо!
CSS
Подскажите пожалуйста, мне нужно при загрузке сайта выбрать определенный файл header.php
(этих файлов два, под разные устройства ) Сейчас выбор нужного файла происходит на заголовка запроса браузера User-Agent. Те учитывая выбор опер системы (Windows или Android) я подгружаю нужный header.php. Но этого недостаточно, мне еще нужно учитывать параметр — CSS ширину устройства--.Те в первом же ответе от сервера должен отправляться контент с правильным файлом header.php.Метод windows.matchMedia отработает уже после получения контента, после построения DOM.
И вот результат: «spacser-shop.com.ua». Еще сыровато, но все впереди. С меню бургер или гамбургер разберусь и будет топ.
До этого стоял и стоит код:
Раньше прокатывал под мобильную версию. Но с 2021 г. начал замечать в «search.google.com», что сайт не соответствует требованиям об удобстве страниц для мобильных. С каждым днем +20 страниц.
Но вашей статьей очень доволен. Спасибо.
Я создал в коде html 3 варианта расположения блоков. Как сделать так, чтоб блоки меняли размеры и перестраивались в зависимости от ширины экрана? Необходимо использовать медиа-запросы или JavaScript (скриншот)?
Спасибо!
вот этот код даёт только один блок слева при 1000рх, как получить второй?
Если нужно просто разбить контент, то можно использовать колонки (column-count). Про создание многоколоночного текста можно почитать в этой статье.
Вот видео :https://yadi.sk/i/iU9sBd6YiSWMYA (20 секнуд)и если не. трудно не могли бы вы телеграмм оставить?
Такой вопрос, применил в js
if (window.matchMedia('screen and (max-width: 543px)').matches) {}
Всё работает, но! например, при повороте экрана на большой мобилке не отображается большое меню (а должно), плюс пользователь всегда может сжать браузер
Отсюда вопрос: как сделать так, чтобы js «слушал» изменение размера?
Так, конечно, у вас код сработает один раз.
В этом случае его нужно добавить в обработчик события, который будет вызываться при смене размеров экрана:
576px, 768px, и т.д. — это значения по умолчанию. Их можно изменить. Скорее всего вы используете сборку Bootstrap, в которой эти значения по умолчанию переопределены.
Извиняюсь может я слишком загнался по этому вопросу и можно закончить проект с теми брейкпоинтами что есть, но очень хочется разобраться как это работает)
Первое CSS правило отрабатывает всегда. Оно задаёт .container 100% ширину того блока, в который он помещён и центрирует его в нём в горизонтальном направлении по центру. Если ширина viewport меньше 576px, то остальные правила не отрабатывают. В остальных правилах имеются условия, и они будут отрабатывать только в том случае, если ширина viewport бразуера пользователя будет не меньше указанной величины (min-width).
Если ширина viewport браузера пользователя больше или равно 576px и меньше 768px то к .container применятся все CSS свойства заданные в первом правиле и CSS свойство max-width: 540px. Т.к. 2 правило проходит по условию.
Если ширина viewport бразуера пользователя больше или равно 768px и меньше 992px, то к .container применятся все CSS свойства, заданные в первом правиле, max-width: 540px и max-width: 720px. Т.к. 2 и 3 правило проходит по условию. Но CSS свойство max-width: 720px расположено ниже по коду, чем CSS-свойство max-width: 540px. В результате будет применены все CSS свойства, заданные в первом правиле и max-width: 720px.
И т.д.
После неё сработают следующие стили, т.к. они не заключены в @media (min-width: 1200px) { … }. В этом случае они переопределят те что были, т.к. они идут после них.
В этом случае вы в самом начале пишите стили для самых маленьких устройств без использования "@media (min-width)".
Затем переходите к следующей ширине после самых маленьких устройств. На этом этапе переопределяете существующие стили, если они должны для данной ширины иметь другой вид, и при необходимости добавляете новые. Для этого вы их заключаете в "@media (min-width)".
При этом этот фрагмент стилей должен располагаться после дефолтных стилей.
Затем переходите к следующей ширине и т.д. При этом важно соблюдать порядок следования фрагментов, т.е. сначала стили без "@media (min-width)", потом, например, с использованием правила "@media (min-width: 576px)", далее с "@media (min-width: 768px)" и т.д.
Если вы проектируете, начиная с самого большого размера, то в этом случае лучше создавать наоборот. Т.е. сначала создаёте дефолтные стили, которые будут определять дизайн веб проекта на самых больших экранах. Далее переходите к более маленьким. На каждом из этих этапов вы переопределяете существующие стили, действующие на эту ширину и заключаете их в @media (max-width), чтобы их действие не распространилась на более большую ширину. Но этот вариант разработки обычно не используют, предпочитая стратегию «Mobile First.
P.S: нет ли у вас на сайте видео примера такой верстки?
/* стили, которые будут применены к элементам страницы с рабочей областью не больше 1199 пикселей */
размер экрана iphone se 1136x640 то есть по идее на портерной ориентации он должен сработать, а на альбомной — нет, но по факту получается что он срабатывает и в том и другом случае.
Если изменять окно браузера то все работает корректно, на телефонах по другому пиксели считаются?
Например, для экранов, имеющих минимальную ширину 1300px:
Начал разбираться с медиа запросами почитал примеры на хабре попробовал ради эксперимента, и сразу же столкнулся с вопросом.
Ниже код: Просматриваем в Chrome.
По F12 открываем консоль, включаем просмотр на разных устройствах и начинаем с самого начала. BlackBerry Z30 с размерами 360 на 640 — прописали медиазапросы, все входит, при обеих ориентациях, — все отлично.
Переходим к следующему в списке BlackBerry PlayBook с размерами 600 на 1024, — прописали медиазапросы, подогнали, все отлично, возвращаемся на посмотреть, что произошло с BlackBerry Z30 — все уплыло.
А там у Хрома еще очень длинный список…
Подскажите, как в таких случаях бороться? Скорее даже вопрос во внятном пояснении принципов.
При этом правила необходимо располагать в следующем порядке:
При этом не обязательно их ограничивать с помощью max-width. Т.е. если у вас в браузере CSS ширина рабочей области равно, например 600px. То будут применены CSS-свойства с условием min-width: 576px, т.к. они расположены после тех, которые предназначены для устройств до 576px. А стили для устройств >=768px применены не будут, т.к. текущая ширина устройства не отвечает этому условию.
То-есть порядок прописания контрольных точек критичен?
Т.е. нет смысла делать так:
Т.е. если, например, устройство имеет ширину 375px, то в этом случае какая будет ширина? Другими словами, CSS правило из 1 media запроса никогда применится к блоку с классом main.