Когда media queries — это только начало
Большинство разработчиков, услышав «адаптивный дизайн», сразу думают о трёх-четырёх breakpoints: 320px, 768px, 1024px, 1440px. Поставил media queries на каждый — готово, адаптив есть. На деле это работает примерно как поставить охрану только у входной двери и считать здание защищённым.
Адаптивность — это система. Media queries — один инструмент в этой системе, и далеко не самый интересный. За последние три года CSS получил столько мощных возможностей, что многие вещи, которые раньше требовали десятков строк с breakpoints, теперь решаются одной строкой.
Mobile-first: это философия, а не порядок CSS
Подход «сначала мобильный» — не просто договорённость «пишем стили для маленьких экранов первыми». Это про приоритеты.
Когда дизайнер начинает с десктопа и потом «сжимает» до мобильного, неизбежно возникают компромиссы: таблицы, которые не влезают, кнопки, которые слипаются, меню из пяти уровней, которое нужно впихнуть в гамбургер. Всё это — симптомы десктопного мышления.
Mobile-first заставляет думать о главном: что здесь самое важное? Если на экране 375px должна быть одна кнопка CTA и минимум лишнего — значит, именно это и есть суть страницы. На десктопе потом добавляется второстепенное.
Около 62% мирового трафика в 2025 году идёт с мобильных устройств. В России этот показатель чуть ниже, но устойчиво растёт. Думать в первую очередь о мобильных пользователях — это уже не «хорошая практика», а необходимость.
На уровне CSS это выглядит так: базовые стили — для маленьких экранов, а min-width в media queries добавляет возможности по мере увеличения экрана. Не убирает лишнее, а добавляет нужное.
Fluid typography: clamp() вместо четырёх breakpoints
Типичная проблема: на мобильном нужен заголовок 24px, на десктопе — 48px. Классическое решение — два media query. Но что происходит между 480px и 1200px? Текст резко прыгает в одной точке.
Функция clamp() решает это элегантно:
font-size: clamp(1.5rem, 4vw, 3rem);
Три параметра: минимум, предпочтительное значение (масштабируется с viewport), максимум. Шрифт плавно растёт от 24px на маленьких экранах до 48px на больших — без единого media query.
То же работает для отступов, ширины элементов, высоты блоков. clamp() поддерживается во всех современных браузерах с 2020 года.
Практический пример: у лендинга с секцией hero, где заголовок и подзаголовок — ключевые элементы, clamp() убирает необходимость в отдельных стилях для трёх точек перехода. Меньше кода, меньше мест для ошибок.
CSS Grid и Flexbox: макеты без media queries
Grid с auto-fill и minmax() может адаптироваться сам:
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
Этот код создаёт сетку, которая сама решает, сколько колонок поместится. На мобильном — одна, на планшете — две-три, на десктопе — четыре. Ноль media queries.
Для карточек товаров, портфолио, блога — это стандартное решение. Flexbox с flex-wrap: wrap и правильно выставленными flex-basis даёт похожий эффект для горизонтальных списков. Элементы сами переносятся на следующую строку, когда не помещаются.
Чем меньше media queries — тем меньше состояний, которые нужно проверять при тестировании. Это реально экономит время разработки и снижает число багов.
Container queries: революция для компонентного подхода
Долгие годы media queries были завязаны на ширину viewport — всего окна браузера. Это создавало странные ситуации: компонент карточки должен перестраиваться не тогда, когда уменьшается экран, а когда уменьшается его контейнер. Раньше это решалось JavaScript или дублированием стилей.
Container queries появились в 2023 году и поддерживаются в Chrome, Firefox и Safari. Теперь компонент может реагировать на размер своего родителя:
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
display: flex;
flex-direction: row;
}
}
Карточка вертикальная в узком сайдбаре и горизонтальная в широкой основной колонке — без JavaScript, без дополнительных классов.
Для дизайн-систем и компонентных библиотек это меняет всё. Компонент становится по-настоящему переиспользуемым: он адаптируется к своему контексту, а не к глобальному viewport.
Адаптивные изображения: не просто max-width: 100%
max-width: 100% на изображениях — это базовый минимум, который не решает главное: браузер всё равно загружает полноразмерное изображение на мобильном. Если у вас фото 2400×1600px, оно загрузится даже на телефоне с экраном 390px.
Правильное решение — атрибуты srcset и sizes:
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 800px"
alt="..."
>
Браузер выберет подходящую версию сам, учитывая и ширину экрана, и плотность пикселей. iPhone с Retina-экраном загрузит изображение вдвое больше, чем нужно для стандартного экрана — но ровно столько, чтобы картинка выглядела чётко.
Для изображений с принципиально разными кадрировками — тег <picture> с source и media. Портрет крупным планом на телефоне, широкий пейзаж на десктопе — из одного HTML-элемента.
Правильно настроенные адаптивные изображения могут уменьшить вес страницы на 40–60% для мобильных пользователей. Это напрямую влияет на Core Web Vitals и позиции в поиске.
Новые viewport units: dvh, svh, lvh
Долгое время 100vh был источником боли на мобильных. Проблема: браузер на телефоне меняет высоту viewport в зависимости от того, видна ли адресная строка. 100vh вычислялся на момент загрузки — и hero-секция либо обрезалась, либо имела лишний скролл.
В 2023–2024 годах появились новые единицы:
dvh (dynamic viewport height) — меняется вместе с viewport, учитывает появление и скрытие UI браузера
svh (small viewport height) — минимальный viewport, браузер с видимой адресной строкой
lvh (large viewport height) — максимальный viewport, адресная строка скрыта
Для полноэкранных секций правило простое: min-height: 100dvh вместо 100vh. Это решает проблему «прыгающего» экрана на iOS без JavaScript-хаков.
Touch targets и интерактивность
Адаптивность — это не только визуальная часть. Нажимаемые элементы на мобильном должны быть достаточного размера. Google рекомендует минимум 48×48px для touch target, Apple — 44×44pt.
На практике: кнопка может выглядеть небольшой, но область нажатия должна быть больше. Делается через padding:
.small-button {
padding: 12px 20px;
}
Ещё один аспект — hover-состояния. На десктопе :hover — привычная вещь. На тачскрине её нет, или она ведёт себя странно. Элементы, у которых вся информация спрятана за hover, на мобильном просто не работают. Используйте @media (hover: hover), чтобы hover-эффекты применялись только на устройствах с курсором:
@media (hover: hover) {
.card:hover {
transform: translateY(-4px);
}
}
Производительность как часть адаптивности
Медленный сайт — неадаптивный сайт. 53% мобильных пользователей уходят, если страница грузится больше 3 секунд. Мобильные сети нестабильнее Wi-Fi, процессоры слабее десктопных.
Несколько вещей, которые влияют на скорость на мобильных:
Анимации только через transform и opacity: они обрабатываются на GPU и не вызывают перерисовку страницы. Анимировать width, height, top, left — значит нагружать CPU, что на мобильных ощущается как тормоза.
Ленивая загрузка изображений: loading="lazy" на <img> — один атрибут, который откладывает загрузку изображений вне viewport. Нативно, без JavaScript.
will-change с умом: подсказывает браузеру заранее оптимизировать элемент. Но ставить везде — значит тратить память впустую. Только там, где реально нужна анимация.
Тестирование адаптивности
DevTools браузера — не достаточный инструмент. Эмуляция мобильных устройств в Chrome полезна, но не показывает реальную производительность и не воспроизводит особенности Safari на iOS.
Что реально стоит проверять:
- Реальные устройства: хотя бы один Android и один iPhone разных годов
- BrowserStack или аналоги для проверки специфичных моделей и версий ОС
- Медленное соединение: в DevTools → Network → Slow 3G
- Landscape-ориентация: многие забывают, что телефон можно повернуть
- Zoom до 200%: требование доступности, и часто выявляет проблемы с адаптивом
Отдельно — Safari на iOS. Этот браузер имеет свои особенности с viewport units, position: fixed и некоторыми CSS-функциями. Если сайт тестируется только в Chrome на Windows — неприятные сюрпризы гарантированы.
Как это влияет на стоимость разработки
Правильный адаптивный дизайн — это не дополнительный этап после вёрстки. Это подход с самого начала: mobile-first проектирование, компонентная архитектура с container queries, продуманная работа с изображениями.
Когда адаптивность заложена в основу, она стоит меньше — нет правок после «а почему на телефоне всё едет». Когда её прикручивают потом — часто дешевле переделать заново.
В REEXY мы закладываем полноценную адаптивность в каждый проект: лендинг от 3 500 ₽, корпоративный сайт от 15 000 ₽ — в эту цену уже входит полная кроссбраузерная и кросс-девайс адаптация, а не «смотрите на мобильном, там примерно нормально».
Если сайт уже есть и плохо работает на мобильных, иногда разумнее сделать аудит и точечные правки, чем переделывать целиком. Это зависит от того, насколько глубоко проблема в архитектуре.
Что проверить прямо сейчас
Возьмите телефон и откройте свой сайт. Проверьте:
- Текст читается без зума?
- Кнопки легко нажимать пальцем?
- Изображения не размытые и не обрезанные в неудачном месте?
- Формы заполнять удобно? Клавиатура не перекрывает поля?
- Сайт грузится за разумное время на мобильном интернете?
Если хотя бы на один вопрос ответ «нет» — это точка роста. И, скорее всего, это влияет на конверсию: пользователи просто уходят, не дождавшись загрузки или не сумев нажать нужную кнопку.
Адаптивность измеряется не наличием media queries в коде. Она измеряется тем, насколько удобно пользователю на его конкретном устройстве.