Media queries
@media— правило CSS, которое применяет стили только при выполнении указанных условий: ширина экрана, ориентация, тип устройства, предпочтения пользователя и другие характеристики.
Зачем нужно
Один сайт должен работать на экранах от 320px (телефон) до 2560px (4K-монитор). Media queries позволяют адаптировать layout, размеры шрифтов, отступы и даже показ/скрытие элементов в зависимости от устройства и предпочтений пользователя.
Где используется
- Адаптивные layout-ы (мобильный → планшет → десктоп)
- Изменение навигации для мобильных
- Печатные стили (
@media print) - Предпочтения пользователя (тёмная тема, анимации)
- Feature queries (
@supports)
Предпосылки
- Блочная модель — понимание размеров
- Единицы измерения — единицы в breakpoints
Синтаксис
/* Базовый синтаксис */
@media (условие) {
/* CSS-правила */
}
/* Тип медиа + условие */
@media screen and (min-width: 768px) {
.sidebar { display: block; }
}
/* Только тип медиа */
@media print {
.no-print { display: none; }
}
Условия по ширине
min-width (Mobile First)
/* Базовые стили — для мобильных */
.container {
padding: 16px;
}
/* Планшет и выше */
@media (min-width: 768px) {
.container {
padding: 24px;
max-width: 720px;
margin-inline: auto;
}
}
/* Десктоп */
@media (min-width: 1024px) {
.container {
max-width: 960px;
}
}
/* Большой десктоп */
@media (min-width: 1280px) {
.container {
max-width: 1200px;
}
}
max-width (Desktop First)
/* Базовые стили — для десктопа */
.sidebar {
width: 300px;
}
/* Планшет и ниже */
@media (max-width: 1023px) {
.sidebar {
width: 200px;
}
}
/* Мобильные */
@media (max-width: 767px) {
.sidebar {
display: none;
}
}
Диапазон (range syntax)
/* Только планшеты: 768px — 1023px */
@media (min-width: 768px) and (max-width: 1023px) {
.layout { grid-template-columns: 1fr 1fr; }
}
/* Новый синтаксис (Level 4) — более читаемый */
@media (768px <= width < 1024px) {
.layout { grid-template-columns: 1fr 1fr; }
}
/* Широкие экраны */
@media (width >= 1280px) {
.container { max-width: 1200px; }
}
Популярные breakpoints
/* Мобильные */
/* < 576px — всё по умолчанию (Mobile First) */
/* Маленький планшет */
@media (min-width: 576px) { /* sm */ }
/* Планшет */
@media (min-width: 768px) { /* md */ }
/* Маленький десктоп / ландшафтный планшет */
@media (min-width: 1024px) { /* lg */ }
/* Десктоп */
@media (min-width: 1280px) { /* xl */ }
/* Большой десктоп */
@media (min-width: 1536px) { /* 2xl */ }
Не привязывайтесь к конкретным устройствам. Breakpoints должны определяться контентом — когда layout «ломается», добавляйте media query.
Комбинирование условий
/* AND — оба условия */
@media (min-width: 768px) and (orientation: landscape) {
/* Планшет в ландшафтном режиме */
}
/* OR — через запятую */
@media (max-width: 600px), (orientation: portrait) {
/* Узкий экран ИЛИ портретная ориентация */
}
/* NOT — отрицание */
@media not print {
/* Не для печати */
}
/* ONLY — для старых браузеров */
@media only screen and (min-width: 768px) {
/* Игнорируется старыми браузерами, которые не понимают media queries */
}
Предпочтения пользователя
Тёмная тема
@media (prefers-color-scheme: dark) {
:root {
--bg: #1a1a2e;
--text: #e9ecef;
--surface: #16213e;
}
}
@media (prefers-color-scheme: light) {
:root {
--bg: #ffffff;
--text: #333333;
--surface: #f8f9fa;
}
}
Ограничение анимаций
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
Контрастность
@media (prefers-contrast: high) {
.button {
border: 2px solid black;
}
}
@media print
@media print {
/* Скрыть навигацию, футер, кнопки */
nav, footer, .no-print, button {
display: none !important;
}
/* Чёрный текст на белом фоне */
body {
color: black;
background: white;
font-size: 12pt;
}
/* Показать URL ссылок */
a[href]::after {
content: " (" attr(href) ")";
font-size: 0.8em;
}
/* Избегать разрывов внутри элементов */
.card, img {
break-inside: avoid;
}
}
@supports — Feature queries
/* Проверить поддержку свойства */
@supports (display: grid) {
.layout {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
}
/* Fallback */
@supports not (display: grid) {
.layout {
display: flex;
flex-wrap: wrap;
}
}
/* Комбинация */
@supports (display: grid) and (gap: 20px) {
.grid {
display: grid;
gap: 20px;
}
}
/* Проверка селектора */
@supports selector(:has(*)) {
.parent:has(.active) {
background: #e6f0ff;
}
}
Частые ошибки
- Breakpoints от устройств, а не от контента — iPhone 14 = 393px, но через год будут другие размеры
- Перекрывающиеся диапазоны:
/* ОШИБКА — 768px попадает в оба */ @media (max-width: 768px) { } @media (min-width: 768px) { } /* ПРАВИЛЬНО */ @media (max-width: 767px) { } @media (min-width: 768px) { } - Слишком много breakpoints — обычно достаточно 3–4
- Забыли
<meta name="viewport">— без него media queries не работают на мобильных:<meta name="viewport" content="width=device-width, initial-scale=1">
Практика
- Создать Mobile First layout с 3 breakpoints
- Добавить
@media printстили - Реализовать тёмную тему через
prefers-color-scheme - Использовать
@supportsдля progressive enhancement - Применить range syntax (
width >= 768px)
Связанные темы
- Responsive Design -- принципы — принципы адаптивного дизайна
- Mobile-first подход — подход Mobile First
- Container queries — запросы на уровне контейнера
- Viewport units — единицы вьюпорта