2.25. CSS3-медиазапросы

css3-media-queriesВ 2001 году в HTML4 и CSS2 была введена поддержка аппаратно-зависимых таблиц стилей, позволившая создавать стили и таблицы стилей для определенных типов устройств. В качестве медиа-типов были определены следующие: aural, braille, handheld, print, projection, screen, tty, tv. Таким образом, браузер применял таблицу стилей только в случае, когда активизировался данный тип устройства.

Кроме того, было введено ключевое слово all, которое использовалось, чтобы указать, что таблица стилей применяется ко всем типам носителей.

В HTML4 медиа-запрос записывался следующим образом:

<link rel="stylesheet" type="text/css" media="screen" href="sans-serif.css">
<link rel="stylesheet" type="text/css" media="print" href="serif.css">

Внутри таблицы стилей также можно было объявить, что блоки объявлений должны применяться к определенным типам носителей:

@media screen {
  * {font-family: sans-serif;}
}

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

<link rel="stylesheet" media="screen, 3d-glasses, print and resolution > 90dpi" href="...">

Текущий синтаксис HTML5 и CSS3 напрямую ссылается на первую спецификацию Media Queries, обновляя правила для HTML. Также был расширен список характеристик медиа-носителей.

Медиазапросы, характеристики устройств и разрешения экрана

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

IE: 9.0 (кроме вложенных медиазапросов)
Edge: 12.0
Firefox: 3.5
Chrome: 26.0
Safari: 6.1
Opera: 10.1
iOS Safari: 7.1
Android: 4.4
Chrome for Android: 55.0

colly
Рис. 1. Пример адаптивной верстки на основе медиазапросов

1. Что такое медиа-запрос

В общем случае медиа-запрос состоит из ключевого слова, описывающего тип устройства (необязательный параметр) и выражения, проверяющего характеристики данного устройства. Из всех характеристик чаще всего проверяется ширина устройства width. Медиа-запрос является логическим выражением, которое возвращает истину или ложь.

Медиа-запросы могут быть добавлены следующими способами:

1) С помощью HTML:
<link rel="stylesheet" media="screen and (color)" href="example.css">

2) С помощью правила @import внутри элемента <style> или внешней таблицы стилей:
@import url(color.css) screen and (color);

3) Непосредственно в коде страницы:

<style>
@media (max-width: 600px) {
  #sidebar {display: none;}
}
</style>

4) Внутри таблицы стилей style.css:

@media (max-width: 600px) {
  #sidebar {display: none;}
}

Таблица стилей, прикрепленная через тег <link>, будет загружаться вместе с документом, даже если её медиа-запрос вернет ложь.

Для поддержки медиа-запросов в старых браузерах можно воспользоваться JavaScript-библиотекой css3-mediaqueries.js, доступную по адресу https://code.google.com/archive/p/css3-mediaqueries-js/.

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

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

2.1. Оператор and

Оператор and связывает друг с другом разные условия:

@media screen and (max-width: 600px) {
/* CSS-стили */;
}

Стили этого запроса будут применяться только для экранных устройств с шириной области просмотра не более 600px.

@media (min-width: 600px) and (max-width: 800px) {
/* CSS-стили */;
}

Стили этого запроса будут применяться для всех устройств при ширине области просмотра от 600px до 800px включительно.

Правило @media all and (max-width: 600px) {...} равнозначно правилу @media (max-width: 600px) {...}.

2.2. Оператор запятая

Оператор запятая работает по аналогии с логическим оператором or.

@media screen, projection {
/* CSS-стили */;
}

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

2.3. Оператор not

Оператор not позволяет сработать медиазапросу в противоположном случае. Ключевое слово not добавляется в начало медиазапроса и применяется ко всему запросу целиком, т.е. запрос

@media not all and (monochrome) {...} 

будет эквивалентен запросу

@media not (all and (monochrome)) {...} 

Если медиазапрос составлен с использованием оператора запятая, то отрицание будет распространяться только на ту часть, которая идет до запятой, т.е. запрос

@media not screen and (color), print and (color)

будет эквивалентен запросу

@media (not (screen and (color))), print and (color)

2.4. Оператор only

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

media="only screen and (min-width: 401px) and (max-width: 600px)"

Эти браузеры ожидают список медиа-типов, разделённых запятыми. И, согласно спецификации, они должны отсекать каждое значение непосредственно перед первым неалфавитно-цифровым символом, который не является дефисом. Таким образом, старый браузер должен интерпретировать предыдущий пример как media="only". Поскольку данного типа медиа-типа не существует, то и таблицы стилей будут игнорироваться.

3. Тип носителя

Тип носителя представляет собой тип устройства, например, принтеры, экраны.

Таблица 1. Тип носителя
Значение Описание
all Подходит для всех типов устройств.
print Предназначен для страничных материалов и документов, просматриваемых на экране в режиме предварительного просмотра печати.
screen Предназначен в первую очередь для экранов цветных компьютерных мониторов.
speech Предназначен для синтезаторов речи.

CSS2.1 и Media Queries 3 определяли несколько дополнительных типов, таких как aural, braille, embossed, projection, tty, tv и handheld, но они приняты устаревшими в Media Queries 4 и не будут использоваться.

4. Характеристики носителя

К характеристикам медианосителя относятся проверяемые параметры устройства. Значения, которые используются при задании характеристик, являются контрольными точками.

Таблица 2. Характеристики носителя
Параметр Описание
width Проверяет ширину области просмотра. Значения задаются в единицах длины, px, em и т.д., например, (width: 800px). Обычно для проверки используются минимальные и максимальные значения ширины.
min-width применяет правило если ширина области просмотра больше значения, указанного в запросе, max-width — ширина области просмотра меньше значения, указанного в запросе.
height Проверяет высоту области просмотра. Значения задаются в единицах длины, px, em и т.д., например, (height: 500px). Обычно для проверки используются минимальные и максимальные значения высоты.
min-height применяет правило если высота области просмотра больше значения, указанного в запросе, max-height — высота области просмотра которого меньше значения, указанного в запросе.
aspect-ratio Проверяет соотношение ширины к высоте области просмотра. Широкоэкранный дисплей с соотношением сторон 16:9 может быть помечен как (aspect-ratio: 16/9).
min-aspect-ratio проверяет минимальное соотношение, max-aspect-ratio — максимальное соотношение ширины к высоте области просмотра.
orientation Проверяет ориентацию области просмотра. Принимает два значения: (orientation: portrait) и (orientation: landscape).
resolution Проверяет разрешение экрана (количество пикселей). Значения также могут проверять количество точек на дюйм (dpi) или количество точек на сантиметр (dpcm), например, (resolution: 300dpi).
min-resolution проверяет минимальное разрешение экрана, max-resolution — максимальное.
color Проверяет количество бит на каждый из цветовых компонентов устройства вывода. Например, (min-color: 4) означает, что экран конкретного устройства должен иметь 4-битную глубину цвета.
min-color проверяет минимальное количество бит, max-color — максимальное количество бит.
color-index Проверяет количество записей в таблице подстановки цветов. В качестве значения указывается положительное число, например, (color-index: 256).
min-color-index проверяет минимальное количество записей, max-color-index — максимальное количество записей.
monochrome Проверяет количество битов на пиксель монохромного устройства. Значение задается целым положительным числом, например, (min-monochrome: 8).
min-monochrome проверяет минимальное количество битов, max-monochrome — максимальное количество битов.
-webkit-device-pixel-ratio Задаёт количество физических пикселей устройства на каждый CSS-пиксель.

device-width, device-height, device-aspect-ratio являются устаревшими API, они удалены из Media Queries Level 4.

5. На какие размеры экрана нужно ориентироваться

При составлении медиазапросов нужно ориентироваться на так называемые переломные (контрольные) точки дизайна, т.е. такие значения ширины области просмотра, в которых дизайн сайта существенно меняется, например, появляется горизонтальная полоса прокрутки. Чтобы определить эти точки, нужно открыть сайт в браузере и постепенно уменьшать область просмотра.

Чтобы адаптировать дизайн сайта под разные устройства, необходимо задать разные стили для разных разрешений экранов, используя определённые контрольные точки. Страницы, адаптированные для просмотра на разных устройствах, должны содержать в разделе <head> мета-тег viewport. Он сообщает браузеру, каким образом нужно контролировать размеры и масштаб страницы.

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Таким образом, ширина окна просмотра будет адаптироваться к ширине экрана устройства width=device-width, обеспечивая соотношение 1:1 между пикселями CSS и аппаратными пикселями устройства initial-scale=1.

/* Smartphones (вертикальная и горизонтальная ориентация) ----------- */
@media only screen and (min-width : 320px) and (max-width : 480px) {
/* стили */
}

/* Smartphones (горизонтальная) ----------- */
@media only screen and (min-width: 321px) {
/* стили */
}

/* Smartphones (вертикальная) ----------- */
@media only screen and (max-width: 320px) {
/* стили */
}

/* iPads (вертикальная и горизонтальная) ----------- */
@media only screen and (min-width: 768px) and (max-width: 1024px) {
/* стили */
}

/* iPads (горизонтальная) ----------- */
@media only screen and (min-width: 768px) and (max-width: 1024px) and (orientation: landscape) {
/* стили */
}

/* iPads (вертикальная) ----------- */
@media only screen and (min-width: 768px) and (max-width: 1024px) and (orientation: portrait) {
/* стили */
}

/* iPad 3**********/
@media only screen and (min-width: 768px) and (max-width: 1024px) and (orientation: landscape) and (-webkit-min-device-pixel-ratio: 2) {
/* стили */
}
@media only screen and (min-width: 768px) and (max-width: 1024px) and (orientation: portrait) and (-webkit-min-device-pixel-ratio: 2) {
/* стили */
}

/* Настольные компьютеры и ноутбуки ----------- */
@media only screen  and (min-width: 1224px) {
/* стили */
}

/* Большие экраны ----------- */
@media only screen  and (min-width: 1824px) {
/* стили */
}

/* iPhone 4 ----------- */
@media only screen and (min-width: 320px) and (max-width: 480px) and (orientation: landscape) and (-webkit-min-device-pixel-ratio: 2) {
/* стили */
}
@media only screen and (min-width: 320px) and (max-width: 480px) and (orientation: portrait) and (-webkit-min-device-pixel-ratio: 2) {
/* стили */
}

/* iPhone 5 ----------- */
@media only screen and (min-width: 320px) and (max-height: 568px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 2){
/* стили */
}
@media only screen and (min-width: 320px) and (max-height: 568px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2){
/* стили */
}

/* iPhone 6 ----------- */
@media only screen and (min-width: 375px) and (max-height: 667px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 2){
/* стили */
}
@media only screen and (min-width: 375px) and (max-height: 667px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2){
/* стили */
}

/* iPhone 6+ ----------- */
@media only screen and (min-width: 414px) and (max-height: 736px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 2){
/* стили */
}
@media only screen and (min-width: 414px) and (max-height: 736px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2){
/* стили */
}

/* Samsung Galaxy S3 ----------- */
@media only screen and (min-width: 320px) and (max-height: 640px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 2){
/* стили */
}
@media only screen and (min-width: 320px) and (max-height: 640px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2){
/* стили */
}

/* Samsung Galaxy S4 ----------- */
@media only screen and (min-width: 320px) and (max-height: 640px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 3){
/* стили */
}
@media only screen and (min-width: 320px) and (max-height: 640px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 3){
/* стили */
}

/* Samsung Galaxy S5 ----------- */
@media only screen and (min-width: 360px) and (max-height: 640px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 3){
/* стили */
}
@media only screen and (min-width: 360px) and (max-height: 640px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 3){
/* стили */
}

Чтобы проверить, как выглядит ваш сайт на разных устройствах, можно воспользоваться сервисом Responsive design testing for the masses.

6. Стратегии использования медиазапросов

Для создания дизайна, позволяющего лучшим образом отображать сайт на различных устройствах, используют общие стратегии медиа-запросов:
1) Уменьшение количества колонок (столбцов) и постепенная отмена обтекания для мобильных устройств.
2) Использование свойства max-width вместо width при задании ширины блока-контейнера.
3) Уменьшение полей и отступов на мобильных устройствах (например, нижних отступов между заголовком и текстом, левого отступа для списков и т.п.).
4) Уменьшение размеров шрифтов для мобильных устройств.
5) Превращение линейных навигационных меню в раскрывающиеся.
6) Скрытие второстепенного содержимого на портативных устройствах с помощью display: none.
7) Подключение фоновых изображений уменьшенных размеров для мобильных устройств.

  • Behruz

    Замечательный сайт !!!
    Урок тоже.

  • oaks

    Отлично! то что было нужно.

    • Пожалуйста!

      • oaks

        когда адаптируешь например (min-width: 768px) and (max-width: 1024px) на каком разрешении адаптировать в консоле? выбирать что то между 768 и 1024?

        • Да, верно. Т.е. нужно плавно менять ширину области просмотра от 768 до 1024px и если вы увидите, что что-то обрезается или элементы сдвигаются, хотя они должны быть расположены в строчку, то для этих элементов нужно прописать дополнительные стили в правило @media. Для следующего правила меньшего размера вы берете (max-width: 767px). Чтобы не гадать с разметкой, можно взять готовую сетку, задающую ширину блоков в % и добавить соответствующие классы (айди) в разметку.

          • oaks

            Спасибо!

          • Если будут ещё вопросы — спрашивайте.

          • Ольга

            Здравствуйте. А как менять ширину области просмотра? Если сайт еще не на хостинге? Ширину страницы изменять?

  • Askar Kasumbekov

    этому не понял «-webkit-«

  • Askar Kasumbekov

    only подключает стили или нет ??

    • подключает, только если плотность пикселей составит указанное значение

  • Tatiana Redchits

    Исправьте ошибку в таблице 2: параметр orientation принимает значения landscape и portrait

  • Tatiana Redchits

    Спасибо за урок, очень понятно и содержательно

  • Serg

    Всем привет! Подскажите, как мобильный телефон с шириной экрана 1080px понимает, что ему нужен css с @media (max-width: 640px) например? Заранее спасибо

  • Создание Сайтов

    Непонятно, как отображает этот сервис, с каких параметров он выставляет такие данные. Разработчики новых ипадов и планшетов побеспокоились, чтобы правильно сверстанные сайты корректно вкладывались в монитор этих устройств. И это даже очевидно на моем устаревшем планшете. Я вижу в нем свой сайт таким, каким он отображается на ноутбуке. Сайт вкладывается в планшет в горизонтальном 1024 и в горизонтальном положении 768px.

    Данный сервис отображает видимо уже с зумом, т.е. если пользователь увеличит область страницы. Получается, что в данную область надо вложить свой сайт — переделать дизайн сайта. Это не стоит того.

  • Александр zp

    Вау! У Вас супер классный ресурс! У меня аж настроение улучшилось когда его нашел! Спасибо большое! Меня приятно удивило. Столько полезной информации, особенно по CSS3!
    😉

    • Спасибо! Приятно видеть такие эмоции на мой сайт)))

      • Александр zp

        Я сегодня проснулся и сразу вспомнил, что сайт этот нашел! И радовался лежал)) И друзьям рассказал об этом))

        • А вы меня своим комментарием тоже вдохновили, занялась обновлением страниц, чтобы они были ещё лучше и содержательней. Спасибо, учитесь на здоровье! Спрашивайте, если непонятно как что реализовать, буду рада помочь.

  • Ekaterina

    Ваш сайт просто находка для новичков, очень понятно и доступно написано.
    Скажите, пожалуйста, если я прописала запрос для вертикального отображения
    @media only screen and (min-width: 620px) and (max-width: 720px) and (orientation: portrait) обязательно ли мне прописывать этот же медиазапрос для горизонтального?

    • Спасибо! Вопрос интересный, так как тема медиазапросов содержит, на мой взгляд, много избыточных рекомендаций. Список вариантов медиазапросов составлен на основе стандартных рекомендаций, которые со временем устаревают. Попробуем разобраться, в чём же дело:

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

      2) я периодически разбираю вёрстку вордпрессовских шаблонов и за последние год-два ни разу не встречала ключевое слово not в медиазапросах. Единственное, где могут быть различия — если вы хотите, чтобы для ретина устройств изображения на сайте подгружались лучшего качества, тогда вам придётся использовать специальные медиазапросы. Посмотрите урок адаптивной вёрстки на сайте http://html5book.ru/adaptivnaya-vyorstka-sayta/, заодно можете протестировать, как выглядит страница на мобильных устройствах. Удобный сервис для онлайн-тестирования http://www.responsinator.com/?url=.

  • Алексей

    Добрый день!
    Помогает ли данный медиазапрос, если я например хочу на десктопах скрыть тот или иной элемент?
    Просто я пробую прописать для пункта меню
    @media only screen and (min-width: 1224px) {
    .mega-desc-hide {
    display:none;
    }
    }

    @media only screen and (min-width: 1824px) {
    .mega-desc-hide {
    display:none;
    }
    }

    Но он не скрывается. Хотя если прописать для меньших экранов то он скрывается.
    Заранее благодарю за ответ

    • Добрый день! Не срабатывает, потому что ключевое слово only подключает стили для браузеров, которые не поддерживают медиа запросы (то есть старые браузеры), а не подключает эти стили ТОЛЬКО для. На данный момент это не имеет смысла, поэтому пишите просто @media (min-width: 1224px) {mega-desc-hide {display:none;}}

      • Алексей

        Спасибо! только это не помогло. Все равно не скрывает

      • Алексей

        Может подскажете?
        Необходимо чтобы в разделе меню «Контакты», пункт «Наши контакты» скрывался на десктопах и был виден только на мобильной версии. Буду очень признателен

        • Объясню, почему не срабатывает. Посмотрите на картинке, как для элементов списка прописаны стили:

          https://uploads.disquscdn.com/images/1b4bba715316a09f5ce6103c6fb0023e29c3bde79b697d94c5728e8f43125441.png

          То есть используется сложный селектор #mega-menu-wrap-primary #mega-menu-primary li.mega-menu-item.
          Поэтому, чтобы отключить нужный пункт меню, возьмём его айди и добавим к этой длинной строчке:
          #mega-menu-wrap-primary #mega-menu-primary li.mega-menu-item #mega-menu-item-4663 {display:none;}

  • Ekaterina

    Елена, подскажите пожалуйста, как прописать медиа запросы для моб.устройств именно для изображений? А то у меня на сайте и текст и видео адаптируются под мобильные устройства, а картинки нет. Нужно это как-то исправить.

  • Dmytro Petrychenko

    Добрый день. Подскажите где искать ответ — при открытой консоле браузера все медиазапросы работают. Как только консоль закрыта — нет. Т.е. Если менять ширину браузера вручную, двигать, — ничего не работает. Спасибо.

    • Здравствуйте. Если я вас правильно поняла — вы хотите убедиться, что медиазапросы вообще работают? Если так, вы можете воспользоваться сервисом http://www.responsinator.com для проверки отображения страниц сайта на разных устройствах.

      • Dmytro Petrychenko

        Спасибо за ресурс. Проблема отображения в браузере была по причине ошибки — я написал макс-девайс-виз, а нужно макс-виз.

        • Пожалуйста. Интересная ошибка. Не пользуйтесь свойствами device-width, device-height, device-aspect-ratio, они являются устаревшими API и удалены из Media Queries Level 4.

  • Ольга

    Здравствуйте. Подскажите, как менять ширину просмотра браузера? Ширину страницы изменять? Перетаскиванием? Если сайт еще не на хостинге? Сначала width: 320px например а потом уменьшить окно перетаскиванием?

  • Ольга

    Да, что от большего к меньшему я поняла, когда пиксели в проценты переводила. Книгу Итана Маркотта прочитала. Спасибо огромное, я не знала что такой сервис есть у браузера.

  • Стас

    У меня такой вопрос: Если я сверстал сайт на FlexBox технологии, стоит вообще использовать медиа запросы? Или использования FlexBox технологии достаточно для адаптива?

    • Без медиа запросов не обойтись. При небольших разрешениях экрана нужно будет уменьшать количество блоков в ряду.

      • Стас

        У меня еще вопрос касательно медиа запросов. Разрешения экранов я должен сам выбирать исходя из поведения сайта при уменьшении? Или все же есть какие-то необходимые разрешения?

        • Всё зависит от содержимого страниц и ширины основного контейнера. Реальных размеров устройств намного больше, чем стандартных размеров, поэтому чтобы сделать вёрстку более универсальной, лучше отслеживать изменения при плавном уменьшении окна браузера. При этом можно не только количество блоков в сетке менять, но и размер шрифта.

    • Ярослав Горохов

      flex вообще можно использовать только в react native 🙂 больше не где он не работате

      • Dron N

        Да вроде всё работает в Chrome под Android.

      • Sergey Cherepanov

        может сначала стоит заглянуть в can i use it? Уж гриды потихоньку надо осваивать, а еще flex’ов остерегаются.

  • Крутой Инфо

    Откуда браузеры знают про слово only, если они не поддерживают медиа запросы?