Перейти до основного вмісту
Версія: Далі

Медіа-запити

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

Медіа-запити - стилі для різних пристроїв

Алгоритм застосування стилів наступний:

  • Розробник описує набір медіа-запитів і CSS-правил всередині них.
  • Браузер відстежує зміну розміру в'юпорту.
  • Браузер застосовує CSS-правила з медіа-запитів, що відповідають поточному розміру в'юпорту.

Тобто медіа-запити - це інструкції на зразок: «коли сторінку відкрили на десктопі, я хочу, щоб колір тексту був червоним, а у разі відкриття на телефоні - зеленим».

Синтаксис

@media media-type and (media-feature) {
/*
* Набір CSS-правил, які потрібно застосувати до документа,
* якщо дотримуються умови перевірки медіатипу і виразу
*/
}

Медіа-запит - це спеціальна CSS-конструкція, яка оголошується директивою @media, за якою може йти тип пристрою (media-type) і медіа-функції (media-feature) - вирази, що перевірять характеристики пристрою (наприклад ширину в'юпорту). Медіа-функція - це логічний вираз, який повертає істину (вірно) або хибність (невірно).

Наприклад, якщо необхідно зробити фон <body> помаранчевим при ширині в'юпорту 900px і ширше, необхідно записати наступний медіа-запит.

styles.css
@media screen and (min-width: 900px) {
body {
background-color: orange;
}
}

Людською мовою це можна прочитати як: «якщо сторінка відображається на екрані, ширина якого не менше 900 пікселів, необхідно застосувати вказане CSS-правило».

Перейдіть на сторінку прикладу, клікнувши у верхньому правому куті редактора на Edit on Codepen, і змінюйте ширину області з результатом. Колір фону <body> буде змінюватися, залежно від ширини в'юпорту, вказаної в медіа-запитах.

Умова перевірки може бути настільки складною або простою, наскільки цього вимагає ситуація. Здебільшого достатньо вказати медіа-тип пристрою (найчастіше screen), і перевірити тільки ширину в'юпорту.

styles.css
/*
Цей медіа-запит застосується під час друку документа.
*/
@media print {
/* ... */
}

/*
Цей медіа-запит застосується при ширині в'юпорту більше 400px.
*/
@media screen and (min-width: 400px) {
/* ... */
}

/*
Тип screen можна не вказувати, якщо стилі пишуться тільки для екранів.
*/
@media (min-width: 400px) {
/* ... */
}

Медіа-типи

Медіа-тип використовується для опису типу пристроїв, на яких може відображатися веб-сторінка. Всього існує три типи, які підтримуються всіма сучасними браузерами.

  • all - якщо не вказати тип носія, за замовчуванням буде використано це значення, яке означає будь-який пристрій.
  • print - відповідає принтерам і пристроям, призначених для відтворення друкованого варіанту, наприклад веб-браузера, що відображає документ у режимі «Попередній перегляд».
  • screen - описує пристрої з фізичним екраном: смартфони, планшети, монітори, телевізори тощо. Тобто все, що не охоплює тип print.

Медіа-функції

Дві медіа-функції, що найчастіше використовуються і дозволяють визначати ширину в'юпорту браузера - min-width і max-width. Вказується мінімальна (min-width) або максимальна (max-width) допустима ширина в'юпорту, за якої застосовуються правила з медіа-запитів.

styles.css
/* Застосується, коли ширина в'юпорту більша за 900px */
@media (min-width: 900px) {
body {
background-color: green;
}
}

/* Застосується, коли ширина в'юпорту менша за 600px */
@media (max-width: 600px) {
body {
background-color: yellow;
}
}

Якщо уявити ширину в'юпорту як пряму від 0 до нескінченності, то ми описуємо проміжок, на якому необхідно застосувати якісь стилі.

Ілюстрація проміжків до 400 і після 900 пікселів
Корисно

Розмір в'юпорту, за якого вся верстка або її окремі частини змінюють свої стилі, тобто змінюється дизайн, називається точкою перелому (breakpoint).

При зміні ширини в'юпорту в прикладі до 600px, фон <body> буде жовтого кольору, а після 900px - зеленого. У проміжку від 601px до 899px - колір білий, значення вказане за замовчуванням, тому що жоден медіа-запит не підійде.

А як описати проміжок, наприклад від 600px до 900px? Необхідно використовувати логічні оператори для складових медіа-функцій.

Логічні оператори

Медіа-тип і медіа-функції можуть бути розділені необов'язковими логічними операторами not, and і only - значення за замовчуванням. Повний синтаксис медіа-запиту виглядає наступним чином.

@media only|not media-type only|and|not (media-feature) {
/*
Набір CSS-правил, які потрібно застосувати до документа,
якщо виконується умова перевірки медіатипу і виразу
*/
}

Оператор and

Оператор and (буквально «І») використовується не тільки між типом носія і медіа-умовою, але і для зв'язування декількох медіа-функцій з перевірками значень.

styles.css
@media screen and (min-width: 400px) and (max-width: 800px) {
body {
background-color: red;
}
}

Такий медіа-запит виконається тільки, якщо веб-сторінка відкрита на екрані, а ширина в'юпорту знаходиться в діапазоні від 400px до 800px.

Ілюстрація відрізка від 400 до 800 пікселів

Оператор ,

Оператор , (буквально «АБО») дозволяє вказати набір виразів, при виконанні хочаб одного з них, виконається медіа-запит.

Наприклад, необхідно застосувати стилі в діапазоні до 600px або після 900px.

@media (max-width: 600px), (min-width: 900px) {
body {
background-color: orange;
}
}
Ілюстрація проміжків до 400 і після 900 пікселів

Тобто це просто перелічення набору медіа-запитів, за яких повинні застосуватися стилі. Це можна записати як два різних медіа-запити. Але тоді код стилів <body> буде дублюватися.

@media (max-width: 600px) {
body {
background-color: orange;
}
}

@media (min-width: 900px) {
body {
background-color: orange;
}
}
Корисно

У майбутніх редакціях CSS, оператор , буде замінений на оператор or.

Оператор not

Оператор not (буквально «НЕ») дозволяє зробити заперечення, тобто скасувати медіа-запит. Ключове слово not додається на початку медіа-запиту і застосовується до всього запиту. Використовується дуже рідко, в якихось специфічних випадках.

Наприклад, запишемо умову, за якої стилі повинні застосуватися скрізь, крім друку.

@media not print {
/* ... */
}

При використанні оператора not обов'язково повинен бути зазначений тип носія, тому що за замовчуванням для нього буде встановлено значення all і вираз not all буде читатися буквально як «не всі», і медіа-запит ніколи не виконається.

styles.css
/* Ніколи не виконається */
@media not (max-width: 500px) {
/* ... */
}

/* Виконається, якщо ширина буде більша за 500px. */
@media not screen and (max-width: 500px) {
body {
background-color: tomato;
}
}

/*
В такому разі, для простоти читання коду
краще використовувати min-width: 500px.
*/
@media (min-width: 500px) {
body {
background-color: tomato;
}
}

Перевизначення стилів

Ніщо не заважає браузеру застосувати більше одного медіа-запиту одночасно, якщо вони підходять за умовою. Медіа-запити не додають специфічності селекторам, які вони містять, але порядок правил як і раніше має значення. Тобто правила, що знаходяться в медіа-запитах, беруть участь у стандартному каскадуванні під час складання фінальних стилів елемента.

styles.css
/* Базовий стиль */
body {
background-color: #fff;
}

/* На 900px і ширше перевизначаємо фон */
@media screen and (min-width: 900px) {
body {
background-color: #388e3c;
}
}

В інструментах розробника можна наочно побачити, як застосовуються CSS-правила і перевизначається колір фону елемента <body>.

Перевизначення стилів в медіа-запитах

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

Таким чином в інструментах розробника будуть виглядати стилі елемента <body> при ширині в'юпорту більшої за 900px.

Глибоке перевизначення стилів в медіа-запитах