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

CSS медиа-запросы (media queries)
Содержание:
  1. Что такое медиа-запросы
  2. Синтаксис
  3. Типы устройств
  4. Логические операторы
  5. Медиа-характеристики
  6. Медиа-запросы в <link> и @import
  7. Дополнения из Media Queries Level 4
  8. Код JavaScript, учитывающий параметры устройств
  9. Комментарии

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

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

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

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

Поддержка браузерами CSS3 медиа-запросов (media queries)

Поддержка медиа-запросов в браузере IE8 осуществляется посредством подключения к странице скрипта «respond.js»:

HTML
<!-- 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 к странице осуществляется так:

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

Синтаксис

Создание медиа-запроса начинается с ключевого слова @media после которого указывается одно или несколько условий. В качестве условия можно указывать тип устройства или требования к определённой характеристике. Требование к определённой характеристике записывается в круглых скобках.

Комбинирование нескольких условий выполняется с помощью логических операторов.

После составления @media, стили, указанные в нём, будут применяться только в том случае, когда итоговый результат вычисления условий является истинной.

Пример медиа-запроса с одним условием:

CSS
@media screen {
  /* стили будут применяться, когда условие истинно */
}

Пример медиа-запроса с комбинированием нескольких условий:

CSS
@media (min-width: 992px) and (max-width: 1199.98px) { ... }

Типы устройств

В @media можно указывать определённые типы устройств:

  • all – для всех;
  • print – для принтеров и в режиме предварительного просмотра страницы перед печатью;
  • screen – для устройств с экранами;
  • speech – для программ чтения с экрана.

Например, этот @media только для экранов:

CSS
@media screen { ... }

А здесь для экранов и принтеров:

CSS
@media screen, print { ... }

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

Логические операторы and, , (запятая), not и only предназначены для создания сложных медиа-запросов.

and

Оператор and используется для объединения нескольких условий. В этом случае их результат будет истинным, когда каждое из них будет истинным.

Например, следующий @media будет применяться только при выполнении всех трёх условий (это экран, width >= 1200px и ориентация landscape):

CSS
@media screen and (min-width: 1200px) and (orientation: landscape) { ... }

, (запятая)

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

В этом примере стили будут применяться к странице в двух случаях. Когда width >= 544px или ориентация portrait.

CSS
@media (min-width: 544px), (orientation: landscape) { ... }

not

Ключевое слово not используется для отрицания.

При использовании not с and отрицание работает для всего медиа-запроса. При этом, когда указываем not необходимо обязательно задавать тип устройства.

Например, применим стили только в том случае, когда не (экран и width >= 411px и height >= 731px).

CSS
@media not screen and (min-width: 411px) and (min-height: 731px) { ... }

При использовании not в выражении с запятой он добавляет отрицание только для этой части.

Например, применим стили когда истинно следующее условие: не экран или не width >= 411px.

CSS
@media not screen, not (min-width: 411px) { ... }

only

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

Медиа-характеристики

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

Каждая характеристика в @media должна быть заключена в круглые скобки.

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

width

Медиа-характеристика width позволяет задать условие на равенство ширины области просмотра определённому значению.

Например, применим CSS только для viewport с шириной 320px.

CSS
@media (width: 320px) { ... }

Для определения диапазона можно использовать min-width и max-width.

Например, @media для ширины viewport от 576px до 1200px:

CSS
@media (min-width: 576px) and (max-width: 1199.98px) { ... }

Для ширины больше 768px:

CSS
@media (min-width: 768px) { ... }

Если нужно меньше 1400px:

CSS
@media (max-width: 1399.98px) { ... }

height

Для задания условий в отношении высоты viewport можно использовать height, min-height и max-height.

Например, @media для высоты viewport больше 720px:

CSS
@media (min-height: 720px) { ... }

orientation

С помощью orientation можно установить те или иные стили в зависимости от того, в каком режиме (альбомном или портретном) отображается сайт.

Например, в зависимости от ориентации viewport будем отображать разные картинки:

CSS
@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.

CSS
/* 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:

CSS
/* Default */
p {
  font-size: 16px;
}

/* Minimum resolution */
@media (min-resolution: 150dpi) {
  p {
    font-size: 14px;
  }
}

Стили для печати страницы с плотностью пикселей больше 300dpi:

CSS
@media print and (min-resolution: 300dpi) { ... }

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

HTML
<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:

CSS
@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 (по умолчанию):

CSS
/* Устройства с очень маленьким экраном (смартфоны, меньше 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. Это заставит их работать только в указанном диапазоне.

CSS
@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):

CSS
/* 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, которые можно применять только в обратном порядке (в порядке убывания ширины области просмотра окна браузера):

CSS
/* 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, которые можно использовать в таблице стилей в любой последовательности:

CSS
/* 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:

CSS
/* для устройств, в которых основной механизм ввода позволяет навести указатель на элемент */
@media (hover: hover) {
  /* ... */
}
/* если основное устройство ввода не позволяет навести указатель на элемент */
@media (hover: none) {
  /* ... */
}

Медиа-функция pointer позволяет нам адаптировать взаимодействие с сайтом в зависимости от наличия указателя у основного механизма ввода и его точности. Она может иметь одно из трёх значений:

  • none – нет указателя (например, смартфоны, взаимодействие с которыми осуществляется с помощью пальцев);
  • coarse – имеет указатель с ограниченной точностью (например, пульт дистанционного управления Smart TV);
  • fine – имеет точное указательное устройство (например: мышь, тачпад или стилус).

Пример объединения этих функций для определения устройств разных типов:

CSS
/* смартфоны, устройства с сенсорными экранами */
@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 медиа-запросов:

JavaScript
// создаём новый объект MediaQueryList, с помощью которого хотим проверить, больше ли ширина области просмотра 768px
const mediaQuery = window.matchMedia('(min-width: 768px)');
// получаем значение свойства matches, и проверяем является ли оно истинным
if (mediaQuery.matches) {
  // если matches содержит true, то выведется alert
  alert('Документ соотвествует медиа-запросу!');
}

Таким образом, суть работы в JavaScript сводится к передаче строки медиа-запроса в matchMedia(), и последующей проверки свойства matches. Это свойство доступно только для чтение и содержит логическое значение. true – если документ соотвествует медиа-запросу, false – в противном случае.

Например, установим цвет фона <body> в зависимости от ширины области просмотра:

JavaScript
if (window.matchMedia('screen and (width >= 768px)').matches) {
  document.body.style.backgroundColor = 'black';
} else {
  document.body.style.backgroundColor = 'yellow';
}

Этот код выполнится один раз и при изменении размера области просмотра цвет фона <body> не обновится.

Если нам нужно реагировать на изменения статуса медиа-запроса, то можно воспользоваться методом addListener(). Этот метод принимает функцию обратного вызова, которая будет вызываться каждый раз при изменении статуса медиа-запроса:

JavaScript
// создаём медиа-запрос
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.

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

Комментарии: 43

Николай
Николай
Александр, добрый день! Подскажите как лучше сделать?
Задача: Нужно сделать рекламные блоки для мобильной и pc версии. т.е чтобы на мобильных устройствах отображалась одна реклама и на компьютерах другая.
В голову приходит что то на вроде этого варианта, но кажется этот вариант топорным, если не затруднить можете подсказать со своего взгляда, норм вариант? Либо делается более грамотно и проще?
Спасибо!

<div class="reklama_Mobile">
<script>RTB_Mobrec</script>
<div class="reklama_PC">
<script>RTB_PCrec</script>
</div>
</div>
CSS

@media screen and (min-width: 480px) {
  .reklama_mobile {
    display: none;
  }
}

@media (max-width: 480px) { 
  .reklama_PC {
    display: none;
  }
}
Александр Мальцев
Александр Мальцев
Добрый день! Я так понимаю, будут вставлены 2 рекламных блока. Просто один из них не будет виден. Если так, то лучше через JavaScript это сделать. Тут нужно просто определить ширину с помощью JavaScript, и вставить либо один, либо другой блок рекламы.
vorap
vorap
Добрый день!
Подскажите пожалуйста, мне нужно при загрузке сайта выбрать определенный файл header.php
(этих файлов два, под разные устройства ) Сейчас выбор нужного файла происходит на заголовка запроса браузера User-Agent. Те учитывая выбор опер системы (Windows или Android) я подгружаю нужный header.php. Но этого недостаточно, мне еще нужно учитывать параметр — CSS ширину устройства--.Те в первом же ответе от сервера должен отправляться контент с правильным файлом header.php.Метод windows.matchMedia отработает уже после получения контента, после построения DOM.
twelve
twelve
Благодарю, отличная статья. Я не опытный пользователь, но за 2 дня разобрался.
И вот результат: «spacser-shop.com.ua». Еще сыровато, но все впереди. С меню бургер или гамбургер разберусь и будет топ.
До этого стоял и стоит код:
<meta name="viewport" content="width=device-width, initial-scale=1">
Раньше прокатывал под мобильную версию. Но с 2021 г. начал замечать в «search.google.com», что сайт не соответствует требованиям об удобстве страниц для мобильных. С каждым днем +20 страниц.
Но вашей статьей очень доволен. Спасибо.
евгений
евгений
Добрый день! Подскажите, пожалуйста, как перестроить расположение блоков в зависимости от устройства?
Я создал в коде html 3 варианта расположения блоков. Как сделать так, чтоб блоки меняли размеры и перестраивались в зависимости от ширины экрана? Необходимо использовать медиа-запросы или JavaScript (скриншот)?
<!-- Смартфон: экран до 768px -->
<div class="01 container">
  <div class="row">
    <div class="col-6" id="xs1">1</div>
    <div class="col-6" id="xs2">2</div>
    <div class="col" id="xs3">3</div>
  </div>
</div>
<!-- Планшет: экран 768px - 1200px -->
<div class="02 container">
  <div class="row">
    <div class="col-md-2" id="md1">1</div>
    <div class="col-md-5" id="md2">2</div>
    <div class="col-md-5" id="md3">3</div>
  </div>
</div>
<!-- Десктоп: >= 1200px -->
<div class="03 container">
  <div class="row">
    <div class="col-xl-4" id="xl1">1</div>
    <div class="col-xl-5" id="xl2">2</div>
    <div class="col-xl-3" id="xl3">3</div>
  </div>
</div>
Спасибо!
евгений
евгений
Уже разобрался!
Александр Мальцев
Александр Мальцев
Привет! Отлично!
Ola
Ola
Супер! Спасибо Вам большое за ваше время и работу!!!
Александр Мальцев
Александр Мальцев
Спасибо! Очень приятно читать такие отзывы.
Olha
Olha
Здравствуйте. Подскажите, пожалуйста, можно ли с помощью медиа запроса «разбить» блок? при отображении на ширине 480px должен отображаться один блок с текстом, а при 1000рх и больше — он должен разбиваться на два одинаковых по ширине, по бокам страницы.
вот этот код даёт только один блок слева при 1000рх, как получить второй?
body {
  min-width: 480px;
  overflow-x: hidden;
}
.company__left { 
  border-top: 8px solid #1C5395;
  border-bottom: 8px solid #D28C57;
  background-color: #FCFCFD;
  position: absolute;
  width: 365px;
  height: 1148px;
  left: calc(50% - 365px/2 - 0.5px);
  top: 6011px;
}

@media (min-width: 768px) {
  .company__left {
    height: 980px;
    left: calc(50% - 365px/2 - 133.5px);
    top: 4748px;
  }
}

@media (min-width: 1000px) {
  .company__left {
    height: 605px;
    left: calc(50% - 365px/2 - 317.5px);
    top: 4748px;
  }
}

@media (min-width: 1920px) {
  .company__left {
    width: 479px;
    left: calc(50% - 479px/2 - 400.5px);
    top: 3846px;
  }
}
Александр Мальцев
Александр Мальцев
Здравствуйте. Вам необходимо создать 2 блока. На маленьких экранах в этом случае следует отображать один блок, а второй – скрывать (display: none). На больших экранах отображать 2 блока с нужной шириной. Это если вам нужно создать именно блоки.
Если нужно просто разбить контент, то можно использовать колонки (column-count). Про создание многоколоночного текста можно почитать в этой статье.
Olha
Olha
Да, нужны блоки. Получается на большом экране должно быть два блока с текстом и картинка между ними. А на маленьком — один блок с текстом из двух больших блоков, и картинка уже под этим блоком…
Александр Мальцев
Александр Мальцев
Это можно выполнить с помощью CSS Flexbox и медиа-запросов.
Александр
Александр
Привет, я делаю автофилия или же автозаполнение данных и столкнулся с такой проблемой, что делать?
Вот видео :https://yadi.sk/i/iU9sBd6YiSWMYA (20 секнуд)и если не. трудно не могли бы вы телеграмм оставить?
Алексей Чернавцев
Алексей Чернавцев
Добрый день!
Такой вопрос, применил в js

if (window.matchMedia('screen and (max-width: 543px)').matches) {}

Всё работает, но! например, при повороте экрана на большой мобилке не отображается большое меню (а должно), плюс пользователь всегда может сжать браузер

Отсюда вопрос: как сделать так, чтобы js «слушал» изменение размера?
Александр Мальцев
Александр Мальцев
Здравствуйте!
Так, конечно, у вас код сработает один раз.
В этом случае его нужно добавить в обработчик события, который будет вызываться при смене размеров экрана:
window.onresize = function(){
  if (window.matchMedia('screen and (max-width: 543px)').matches) {}
};
Алексей Чернавцев
Алексей Чернавцев
Большое спасибо :)
AleksLT
AleksLT
Может кому-то поможет. Все дело было в работе LiveServer для VSCode. При стандартном открытии html документа все брейкопинты работают хорошо)
AleksLT
AleksLT
Добрый день, подскажите: использую Bootstrap 4.3.1. Сделал макет при помощи готовых классов. При включении панели разработчика и настройки адаптивности, возникла проблема. до 512px работают классы col-sm, с 512px до 660px col-md, с 660px до 799px col-lg. В документации идут значения 576px, 768px, 992px и 1200px. Почему у меня стили присваиваются на непонятных значениях ширины?
<div class="main">
        <div class="container">
            <div class="header">
                <div class="row">
                    <div class="col-sm-12 offset-sm-0 col-md-12 offset-md-0 col-lg-6 offset-lg-0">
                        <div class="main-logo">
                            <img src="../src/img/logo.png" alt="company logo">
                            <h2>Заголовок</h2>
                            <p>Текст</p>
                        </div>
                    </div>
                    <div class="col-sm-12 offset-sm-0 col-md-12 offset-md-0 col-lg-6 offset-lg-0">
                        <div class="contact">
                            <div class="contact-block">
                                    <p></p>
                                    <p></p>
                                    <a href="#" class="vk"></a>
                                    <a href="#" class="inst"></a>
                            </div>
                        </div>
                </div>
            </div>
        </div>
        </div>
</div>
Александр Мальцев
Александр Мальцев
Привет!
576px, 768px, и т.д. — это значения по умолчанию. Их можно изменить. Скорее всего вы используете сборку Bootstrap, в которой эти значения по умолчанию переопределены.
AleksLT
AleksLT
Спасибо большое за ответ, но до этого делал сайт с точно такой же сборкой, сейчас юзаю его все хорошо брейкпоинты стандартные работают.
Медиа запросы в Bootstrap CSS
Извиняюсь может я слишком загнался по этому вопросу и можно закончить проект с теми брейкпоинтами что есть, но очень хочется разобраться как это работает)
Александр Мальцев
Александр Мальцев
Это работает очень просто.

Первое 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.

И т.д.
Иван
Иван
Перечень медиа-запросов для 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 (min-width: 1200px) {… } здесь не обязательна, т.к. после (min-width: 992px) and (max-width: 1199px) будут срабатывать наши основные стили.
Александр Мальцев
Александр Мальцев
Привет! Эта строка обязательна. Если например viewport имеет ширину 1000px, то сначала сработает эта конструкция:
@media (min-width: 992px) and (max-width: 1199px) { ... }
После неё сработают следующие стили, т.к. они не заключены в @media (min-width: 1200px) { … }. В этом случае они переопределят те что были, т.к. они идут после них.
Иван
Иван
Здравствуйте! Спасибо за статью… но помогите разобраться, я никак не могу понять и всё время путаюсь, каким образом делается адаптивность через @media (min-width). Я все время использую @media (max-width). Мне дают макет, я по нему делаю верстку, а потом уменьшаю экран и пишу медиазапросы @media (max-width)… Но min-width идет от меньшего к большему и у меня всё в голове «ломается», ведь изначально уже сделано всё для большего размера, а тут получается каждый брейкпоин идет к большему. Подскажите, как их правильно применять?
Александр Мальцев
Александр Мальцев
"@media (min-width)" удобно использовать, когда вы при разработке дизайна используете стратегию «Mobile First», т.е. сначала пишите стили для отображения страниц на самых маленьких экранах, затем переходите к более крупным и так далее.
В этом случае вы в самом начале пишите стили для самых маленьких устройств без использования "@media (min-width)".
/* дефолтные стили */
h1 {
  font-size: 20px;
  font-weight: bold;
}
Затем переходите к следующей ширине после самых маленьких устройств. На этом этапе переопределяете существующие стили, если они должны для данной ширины иметь другой вид, и при необходимости добавляете новые. Для этого вы их заключаете в "@media (min-width)".
@media (min-width: 576px) {
  h1 {
    font-size: 24px;
  }
}
При этом этот фрагмент стилей должен располагаться после дефолтных стилей.
Затем переходите к следующей ширине и т.д. При этом важно соблюдать порядок следования фрагментов, т.е. сначала стили без "@media (min-width)", потом, например, с использованием правила "@media (min-width: 576px)", далее с "@media (min-width: 768px)" и т.д.

Если вы проектируете, начиная с самого большого размера, то в этом случае лучше создавать наоборот. Т.е. сначала создаёте дефолтные стили, которые будут определять дизайн веб проекта на самых больших экранах. Далее переходите к более маленьким. На каждом из этих этапов вы переопределяете существующие стили, действующие на эту ширину и заключаете их в @media (max-width), чтобы их действие не распространилась на более большую ширину. Но этот вариант разработки обычно не используют, предпочитая стратегию «Mobile First.
Иван
Иван
Спасибо за развернутый ответ! Я конечно, не так давно верстаю, но всё что не смотрю видео уроки, примеры и т.д., везде начинают с верстки макета как он есть, т.е. самый большой размер, а потом уменьшают. Мне стало интересно, т.е. главный CSS файл нужно начать писать для самого маленького разрешения, а потом расширять? У меня сразу в голове прокручивается картина: а как так можно подгадать всё, чтобы дойдя до самого большого размера всё сошлось с макетом, все верхние-нижние отступы и т.д. Ведь когда делаешь вначале по макету, то делаешь почти pix-to-pix, а потом уже произвольно уменьшаешь, чтобы смотрелось. А в случае с «Mobile First», получается мы наугад задаём размеры для мобильного вида и потом увеличиваем их… это ведь надо так подгадать, чтобы в итоге по макету встало *) Или на практике, это не так сложно?
P.S: нет ли у вас на сайте видео примера такой верстки?
Александр Мальцев
Александр Мальцев
Таких видео примеров нет. Но, их можно поискать в Youtube по ключевой фразе «Mobile First». В случае если имеется только большая картинка по который вы строите макет, то придётся просто всё более тщательно продумывать. Начинайте создавать макет, начиная c основного каркаса и сразу под все устройства, начиная с мобильных. Потом переходите к детализации основных структурных блоков, далее к детализации того, что ещё не детализировано и т.д. При этом необходимо создавать так, чтобы готовый блок в некоторой ячейке вашего макета можно было просто перенести в другую ячейку вашего макета без изменения кода CSS. При этом если нужно «pix-to-pix», то оставляйте это под конец. В конце, когда макет будет готов под все устройства немного измените стили для больших экранов, чтобы получить его «pix-to-pix».
shohinform
shohinform
можно ли написать media запрос для каждого карусела?
Александр Мальцев
Александр Мальцев
Не знаю что такое «карусела». Медиа-запросы можете написать под любые размеры, так как вам нужно.
Sergey Ionov
Sergey Ionov
max-width — указывает на то, какой должна быть максимальная рабочая область устройства (браузера).
/* стили, которые будут применены к элементам страницы с рабочей областью больше 1199 пикселей */
@media (min-width: 1199px) { /* Стили CSS ... */ }
Этот пример наверное стоило бы переписать так:
/* стили, которые будут применены к элементам страницы с рабочей областью не больше 1199 пикселей */
@media (max-width: 1199px) { /* Стили CSS ... */ }
Александр Мальцев
Александр Мальцев
Спасибо за дельные замечания. Все эти моменты поправил в статье.
Sergey Ionov
Sergey Ionov
, (запятая) — требует обязательного выполнения хотя бы одного из указанных условий в медиа запросе.
@media (min-width: 544px), (orientation: landscape) { /* Стили CSS ... */ }
Стили CSS в этом примере будут применяться к странице в двух случаях. Т.е. тогда, когда устройство будет иметь viewport не менее 1200 пикселей (включительно) или ориентацию landscape.
Наверное здесь хотели написать не 1200, а 544 пикселей?
Андрей
Андрей
пишу
@media (mах-width: 768px)
размер экрана iphone se 1136x640 то есть по идее на портерной ориентации он должен сработать, а на альбомной — нет, но по факту получается что он срабатывает и в том и другом случае.
Если изменять окно браузера то все работает корректно, на телефонах по другому пиксели считаются?
Александр Мальцев
Александр Мальцев
Познакомьтесь с тем, как работает viewport. На данном устройстве скорее всего установлен коэффициент 2 (CSS разрешение 568х320 пикселей). Т.е. один CSS пиксель формируется с помощью 4 физических пикселей.
aliya
aliya
Здравствуйте, хотелось бы узнать, как вы сделали меню на этом сайте? мой респект)) если не секрет, конечно
Александр Мальцев
Александр Мальцев
Здравствуйте! Конечно не секрет, это обычное Bootstrap меню (компонент Navbar).
Андрей
Андрей
Здравствуйте! Подскажите, можно ли в Bootstrap 4 задать дополнительный медиазапрос, например, для 1300px?
Александр Мальцев
Александр Мальцев
Здравствуйте! Если нужно, конечно создавайте. Тут нет разницы, используете ли вы Bootstrap или нет.
Например, для экранов, имеющих минимальную ширину 1300px:
/* >=1300 */
@media (min-width: 1300px) {
  /* ... */
}
Александр
Александр
Александр, приветствую.
Начал разбираться с медиа запросами почитал примеры на хабре попробовал ради эксперимента, и сразу же столкнулся с вопросом.
Ниже код:
<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 — все уплыло.
А там у Хрома еще очень длинный список…

Подскажите, как в таких случаях бороться? Скорее даже вопрос во внятном пояснении принципов.
Александр Мальцев
Александр Мальцев
При создании адаптивной разметки необходимо определиться с основными контрольными точками. Например, 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 применены не будут, т.к. текущая ширина устройства не отвечает этому условию.
Александр
Александр
Благодарю.
То-есть порядок прописания контрольных точек критичен?
Александр Мальцев
Александр Мальцев
Желательно делать так или жёстко определять диапазоны, чтобы вы знали, какие свойства 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.