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

Статья, в которой познакомимся с медиа запросами и научимся применять их для создания адаптивных сайтов. Рассмотрим основные конструкции media запросов для использования их в вёрстке страниц с использованием фреймворков Bootstrap 3 и Bootstrap 4.

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

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

Медиа запросы появились в спецификации CSS3 и на сегодняшний день поддерживаются во всех современных браузерах (Chrome 4+, Firefox 3.5+, IE 9+, Opera 9+, Safari 4+).

Поддержка браузерами CSS3 медиа запросов (media queries)
Поддержка браузерами CSS3 медиа запросов (media queries)
Поддержка медиа запросов в браузере 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 viewport".

Подключение метатега viewport к странице в большинстве случаях осуществляется так:

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

Синтаксис медиа запросов

Для создания медиа запросов используется следующий синтаксис:

@media условие {
/* стили (они будут выполняться, если устройство соответствует указанному условию)
}

Основные типы устройств:

  • all - все устройства (по умолчанию).
  • print - принтеры и режим предварительного просмотра страницы перед печатью.
  • screen - устройства с дисплеями.

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

  • and - требует обязательного выполнения всех указанных условий.
    Например:
    @media screen and (min-width: 1200px) and (orientation: landscape) { /* Стили CSS ... */ }
    Стили CSS в вышеприведённом примере выполняться только в том случае, если страница будет выводиться на устройство с экраном, иметь область просмотра более 1200 пикселей в ширину, а также находиться в альбомном режиме.
  • , (запятая) - требует обязательного выполнения хотя бы одного из указанных условий в медиа запросе.
    @media (min-width: 544px), (orientation: landscape) { /* Стили CSS ... */ }
    Стили CSS в этом примере будут применяться к странице в двух случаях. Т.е. тогда, когда устройство будет иметь viewport не менее 1200 пикселей (включительно) или ориентацию landscape.
  • not - предназначен для отрицания указанного условия. Имеет по отношению к оператору and меньший приоритет, т.е. оператор not всегда выполняется после and.
    @media not screen and (orientation: portrait), (min-width: 992px) { /* Стили CSS ... */ }
    Стили CSS, находящиеся в этом правиле, будут применены к странице только в том случае, если устройство не является screen и не будет иметь портретную ориентацию. А также они (стили CSS) будут применены к элементам документа ещё тогда, когда устройство (браузер) будет иметь ширину рабочей области не менее 992 пикселя (включительно).
    Т.е. запрос в вышеприведённом примере будет обрабатываться так:
    @media not (screen and (orientation: portrait)), (min-width: 992px) { /* Стили CSS ... */ }

Медиа функции

Для составления условия в @media можно использовать следующие фукнции:

  • width - указывает требования к ширине области просмотра устройства (браузера).
    /* применить стили CSS только для устройств с шириной области просмотра, равной 320px */
    @media (width: 320px) { /* Стили CSS ... */ }
    
  • min-width - задаёт минимальную ширину области viewport в px, em или других единицах.
    /* для устройств (браузеров), которые предоставляют для страницы минимальную ширину области просмотра, равную 544 пикселя */
    @media (min-width: 544px) { /* Стили CSS ... */ }
    
  • max-width - указывает на то, какой должна быть максимальная рабочая область устройства (браузера).
    /* стили, которые будут применены к элементам страницы с рабочей областью больше 1199 пикселей */
    @media (min-width: 1199px) { /* Стили CSS ... */ }
    
  • height, min-height и max-height - задают требования аналогично вышеприведённым функциям, но в отношении высоты viewport.
    /* стили, которые будут применены к элементам страницы в том случае, если viewport браузера будет больше 720px в высоту */
    @media (min-height: 720px) { /* Стили CSS ... */ }
    
  • orientation - функция, которая проверяет то, в каком режиме (portrait или landscape) отображается страница.
    Пример, в котором в зависимости от ориентации экрана, отображается одна или другая картинка:
    /* landscape (альбомный) - это режим, в котором наоборот ширина viewport больше её высоты */
    @media (orientation: landscape) { 
      #background-image { background: url(image1.png) no-repeat; }
    }
    
    /* portrait (портретный) - это режим, в котором высота viewport больше ширины */
    @media (orientation: portrait) { 
      #background-image { background: url(image2.png) no-repeat; }
    }  
    
  • aspect-ratio (min-aspect-ratio, max-aspect-ratio) - позволяют указать то, как ширина устройства должна относиться к высоте. В качестве значений допускается использовать только целые значения.
    /* для дисплеев с соотношением сторон 16/9 */
    @media screen and (device-aspect-ratio: 16/9) { /* Стили CSS ... */ }
    
    /* для дисплеев с соотношением сторон 1336/768 */
    @media screen and (device-aspect-ratio: 1336/768) { /* Стили CSS ... */ }
    
  • resolution (min-resolution, max-resolution) - указывает разрешение (плотность пикселей) устройства вывода. В качестве единиц измерения разрешения используются следующие величины: dpi (количество точек на дюйм), dpcm (количество точек на сантиметр), dppx (количество точек на пиксель).
    /* для экранов, имеющих высокую плотность пикселей 
       (т.е. для таких, у которых отношение аппаратных пикселей к CSS не менее 2) */
    @media screen and (min-resolution: 2dppx) { /* Стили CSS ... */ }
    
    /* при печати с разрешением свыше 300 точек на дюйм */
    @media print and (min-resolution: 300dpi) { /* Стили CSS ... */ }
    

Использование медиа-запросов при подключении файлов CSS

Медиа запросы также можно применять в качестве значения атрибута media элемента link. Это позволит в зависимости от параметров устройства определить, какие файлы CSS необходимо подсоединить к странице, а какие нет. Обычно данный функционал используется тогда, когда к разным классам устройств необходимо применить различные стили CSS.

<!-- Стили xs-styles.css будут подсоединены к странице только на устройствах c шириной меньше 543 пикселей (включительно) -->
<link rel="stylesheet" media="screen and (max-width: 543px)" href="styles-xs.css">

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

/* импортирование стилей из файла styles-xs.css в текущий файл стилей только для устройств, которые предоставляют веб-странице viewport, имеющий ширину 543 пикселя или меньше. */
@import url(styles-xs.css) (max-width: 543px);

Медиа запросы для 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) { ... }

Код JavaScript, учитывающий параметры устройств

Наиболее простой способ создания кода JavaScript, учитывающий параметры устройств (аналогично CSS медиа запросам), осуществляется с помощью метода matchMedia объекта window.

Осуществляется это следующим образом:

// например, проверим, соответствует ли указанный медиа запрос (screen and (max-width: 543px)) устройству
// результат проверки можно получить с помощью свойства matches (true или false)
if (window.matchMedia('screen and (max-width: 543px)').matches) {
  // ... действия, если устройство отвечает медиа запросу
} else {
  // ... действия, если устройство не соответствует значениям медиа запроса
}

Например, эту возможность можно применить для асинхронной загрузки картинок в зависимости от того какой размер viewport имеет устройство (браузер).

Метод matchMedia не поддерживается Internet Explorer 9 и другими старыми браузерами. Для того чтобы обеспечить эту функциональность в старых браузерах можно воспользоваться методом mq библиотеки Modernizr.

Поддержка браузерами метода matchMedia (JavaScript) - ноябрь 2016
Поддержка браузерами метода matchMedia (JavaScript) - ноябрь 2016
if (Modernizr.mq('(max-width: 767px)')) {
  // ... действия, если устройство соответсвуют указанному медиа условию
} else {
  // ... действия, если устройство не отвечает заданному медиа условию
}


   HTML и CSS 0    1886 0

Комментарии (4)

  1. Александр # 0
    Александр, приветствую.
    Начал разбираться с медиа запросами почитал примеры на хабре попробовал ради эксперимента, и сразу же столкнулся с вопросом.
    Ниже код:
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
    <meta http-equiv="Content-Language" content="ru">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>MediaQueryes</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <link href="https://fonts.googleapis.com/css?family=Fira+Sans+Condensed:300,400,600|Play:400,700&subset=cyrillic-ext" rel="stylesheet">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <style>
    	#companyAbout {
    	  background: url(/images/parallax/00004.jpg) center no-repeat fixed; 
    	  background-size: cover;
    	  min-height: 100vh;
    	  height: 100vh;
    	  margin: 0 auto;
    	  width: 100%;
    	  max-width: 2400px;
    	  position: relative;
    	  background:black;
    	}
    	#companyAbout article {
    	  height: 80%;
    	  position: absolute;
    	  text-align: center;
    	  top: 10%;
    	  width: 100%;
    	  color:#ffffff;
    	  padding-left:15%;
    	  padding-right:15%;
    	  font-family:'Fira Sans Condensed', sans-serif;
    	  font-size: 18px;
          line-height: 1.7;
    	  display:inline-block;
    	}
    	.companyAbout-img{
    		display:inline-block;
    		border:0px none;
    		background:none;
    	}
    	.accentuation{
    		width:200px;
    		height:1px;
    		margin-top:7px;
    		border-top:1px solid #ffffff;
    		margin-bottom:40px;
    	}
    	.companyAbout-bottom{
    		border:0px none;
    		background:none;
    		margin-top:40px;
    	}
    	.companyAbout-slogan{
    		font-family:'Play', sans-serif;
    		font-weight:500;
    		font-size:22px;
    	}
    /*-- BlackBerry Z30 --*/
    		/*-- 640 x 360 landscape --*/
    		@media screen and (min-width:360px) and (max-width:640px) { 
    			#companyAbout article{
    				font-size:14px;
    				top:5%;
    				padding-left:5%;
    				padding-right:5%;
    				line-height: 1.2;
    			}
    			.companyAbout-slogan{
    				font-size:17px;
    			}
    			.accentuation{
    				margin-bottom:10px;
    			}
    			.companyAbout-bottom{
    				margin-top:10px;
    			}
    			.toHide{
    				display:none;
    			}
    		} 
    		/*-- 640 x 360 portrait --*/
    		@media screen and (max-width:360px) { 
    			#companyAbout article{
    				font-size:16px;
    				top:5%;
    				padding-left:5%;
    				padding-right:5%;
    				line-height: 1.3;
    			}
    			.companyAbout-slogan{
    				font-size:18px;
    			}
    			.accentuation{
    				margin-bottom:15px;
    			}
    			.companyAbout-bottom{
    				margin-top:15px;
    			}
    			.toHide{
    				display:none;
    			} 
    		}
    /*-- BlackBerry PlayBook --*/
    		/*-- 1024 x 600 landscape --*/
    		@media screen and (min-width:600px) and (max-width:1024px) { 
    			#companyAbout article{
    				font-size:17px;
    				top:10%;
    				padding-left:15%;
    				padding-right:15%;
    				line-height: 1.45;
    			}
    			.companyAbout-slogan{
    				font-size:22px;
    			}
    			.accentuation{
    				margin-bottom:20px;
    			}
    			.companyAbout-bottom{
    				margin-top:20px;
    			}
    		} 
    		/*-- 1024 x 600 portrait --*/
    		@media screen and (max-width:600px) { 
    			#companyAbout article{
    				font-size:20px;
    				top:10%;
    				padding-left:10%;
    				padding-right:10%;
    				line-height: 1.7;
    			}
    			.companyAbout-slogan{
    				font-size:24px;
    				line-height: 1.4;
    			}
    			.accentuation{
    				margin-bottom:40px;
    			}
    			.companyAbout-bottom{
    				margin-top:40px;
    			}
    		}
    </style>
    
    </head>
    
    <body>
    <section id="companyAbout" data-type="background" data-speed="10" class="pages">
      	  <article>
            <div class="companyAbout-img">
            	<img src="images/logo_offcanvas.svg" alt="Logo"/>
            </div>
            <hr class="accentuation">
            <!--<div class="accentuation"></div>-->
          	<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
            <p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. </p>
            <p>Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</p>
            <p>Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?.</p>
            <p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur</p>
            <div class="companyAbout-bottom">
            	<span class="companyAbout-slogan">Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</span>
            </div>
          </article>
    
    </section>
    
    </body>
    </html>
    Просматриваем в Chrome.
    По F12 открываем консоль, включаем просмотр на разных устройствах и начинаем с самого начала. BlackBerry Z30 с размерами 360 на 640 — прописали медиазапросы, все входит, при обеих ориентациях, — все отлично.
    Переходим к следующему в списке BlackBerry PlayBook с размерами 600 на 1024, — прописали медиазапросы, подогнали, все отлично, возвращаемся на посмотреть, что произошло с BlackBerry Z30 — все уплыло.
    А там у Хрома еще очень длинный список…

    Подскажите, как в таких случаях бороться? Скорее даже вопрос во внятном пояснении принципов.
    1. Александр Мальцев # 0
      При создании адаптивной разметки необходимо определиться с основными контрольными точками. Например, 576px, 768px, 992px и 1200px. Эти точек может быть больше или меньше в зависимости от реализуемого макета. Эти точки должны определять изменения в верстке. Т.е. до 576px должна быть одна разметка, при 576px и выше другая, при 768px и больше тоже другая и т.д.

      При этом правила необходимо располагать в следующем порядке:
      /* устройства (до 576px) */
      /* стили... */
       
      /* >= 576px) */
      @media (min-width: 576px) {
        /* стили... */
      
      }
      /* >=768px) */
      @media (min-width: 768px) {
        /* стили... */
      
      }
      /* и т.д. */
      
      При этом не обязательно их ограничивать с помощью max-width. Т.е. если у вас в браузере CSS ширина рабочей области равно, например 600px. То будут применены CSS-свойства с условием min-width: 576px, т.к. они расположены после тех, которые предназначены для устройств до 576px. А стили для устройств >=768px применены не будут, т.к. текущая ширина устройства не отвечает этому условию.
      1. Александр # 0
        Благодарю.
        То-есть порядок прописания контрольных точек критичен?
        1. Александр Мальцев # 0
          Желательно делать так или жёстко определять диапазоны, чтобы вы знали, какие свойства CSS применятся к блокам.
          Т.е. нет смысла делать так:
          @media screen and (min-width:360px) and (max-width:640px) {
            .main {
              width: 100%;
            }
            /* стили... */
          }
          @media screen and (min-width:600px) and (max-width:1024px) {
            .main {
              width: 60%;
            }
            /* стили... */
          }
          @media screen and (max-width:600px) {
            .main {
              width: 80%;
            }
            /* стили... */
          }
          
          Т.е. если, например, устройство имеет ширину 375px, то в этом случае какая будет ширина? Другими словами, CSS правило из 1 media запроса никогда применится к блоку с классом main.

    Вы должны авторизоваться, чтобы оставлять комментарии.