Адаптив: mobile-first, media queries
Адаптив: mobile-first, media queries
Больше половины трафика в вебе - с мобильных. Если сайт не адаптирован - пользователь уйдёт через 3 секунды.
Mobile-first - подход к стилям
Сначала пишешь стили для мобилки (базовые), потом расширяешь для больших экранов через @media (min-width: ...):
/* Базовые стили - для всех (включая мобилки) */
.container {
padding: 16px;
}
.cards {
display: grid;
grid-template-columns: 1fr; /* одна колонка */
gap: 16px;
}
/* Планшет и больше */
@media (min-width: 768px) {
.container { padding: 24px; }
.cards { grid-template-columns: repeat(2, 1fr); }
}
/* Десктоп */
@media (min-width: 1024px) {
.container { padding: 32px; max-width: 1200px; margin: 0 auto; }
.cards { grid-template-columns: repeat(3, 1fr); }
}
Media queries - синтаксис
/* Ширина экрана */
@media (min-width: 768px) { } /* 768px и шире */
@media (max-width: 600px) { } /* 600px и уже */
/* Комбинация */
@media (min-width: 768px) and (max-width: 1023px) { } /* только планшеты */
/* Ориентация */
@media (orientation: landscape) { } /* горизонтальная */
@media (orientation: portrait) { } /* вертикальная */
/* Тёмная тема */
@media (prefers-color-scheme: dark) {
:root {
--color-bg: #1a202c;
--color-text: #e2e8f0;
}
}
/* Уменьшенная анимация (для людей с вестибулярными нарушениями) */
@media (prefers-reduced-motion: reduce) {
* { transition: none !important; animation: none !important; }
}
Типичные брейкпоинты
< 640px Телефон 1 колонка, крупные кнопки, гамбургер-меню
640-1024px Планшет 2 колонки, sidebar может скрываться
1024px+ Десктоп 3+ колонки, sticky sidebar, полное меню
1280px+ Большой max-width контейнера, контент по центру
viewport - обязательный мета-тег
<meta name="viewport" content="width=device-width, initial-scale=1" />
Без него мобильный браузер думает, что ширина экрана 980px, и показывает десктопную версию мелко. С ним - использует реальную ширину устройства.
Адаптивные паттерны
Гамбургер-меню на мобилке
.nav-links {
display: none; /* скрыто на мобилке */
}
.hamburger {
display: block; /* показан на мобилке */
}
@media (min-width: 768px) {
.nav-links {
display: flex;
gap: 24px;
}
.hamburger {
display: none; /* скрыт на десктопе */
}
}
Sidebar скрывается на мобилке
.layout {
display: grid;
grid-template-columns: 1fr;
}
.sidebar {
display: none;
}
@media (min-width: 1024px) {
.layout {
grid-template-columns: 250px 1fr;
}
.sidebar {
display: block;
}
}
Адаптивная типографика
body {
font-size: 16px;
line-height: 1.6;
}
h1 {
font-size: 1.75rem; /* 28px на мобилке */
}
@media (min-width: 768px) {
h1 {
font-size: 2.25rem; /* 36px на десктопе */
}
}
Адаптивные изображения
img {
max-width: 100%; /* не вылезает за контейнер */
height: auto; /* сохраняет пропорции */
}
<!-- Разные изображения для разных экранов -->
<picture>
<source media="(min-width: 1024px)" srcset="hero-large.jpg" />
<source media="(min-width: 640px)" srcset="hero-medium.jpg" />
<img src="hero-small.jpg" alt="Hero" />
</picture>
clamp() - адаптивные значения без media queries
h1 {
font-size: clamp(1.5rem, 4vw, 3rem);
/* минимум 1.5rem, идеально 4vw, максимум 3rem */
}
.container {
padding: clamp(16px, 3vw, 48px);
}
clamp(min, preferred, max) - плавно меняет значение в зависимости от ширины окна. Одна строка вместо трёх media queries.
Единицы vw, vh, dvh
.hero { height: 100vh; } /* 100% высоты viewport */
.full { width: 100vw; } /* 100% ширины viewport */
Проверка адаптивности
В DevTools есть режим эмуляции устройств (Ctrl+Shift+M в Chrome). Можно:
- переключать между размерами устройств
- тестировать touch-события
- симулировать медленное соединение
- проверять тёмный режим через Rendering → Emulate CSS media feature
Мини-задание
- Сделай карточки: 1 колонка на мобиле, 2 на планшете, 3 на десктопе
- Спрячь sidebar на мобиле через
display: noneи@media (min-width: 1024px) - Добавь
prefers-color-scheme: darkдля тёмной темы - Попробуй
clamp()для адаптивного размера шрифта - Открой DevTools и протестируй сайт в режиме мобильного устройства