Урок по треку HTML и CSS 8 мин

Адаптивная вёрстка за 8 минут

Медиазапросы, контейнерные запросы, относительные единицы, clamp и адаптивные картинки.

Адаптивность значит, что один и тот же HTML хорошо выглядит на телефоне, планшете и широком мониторе. В 2026 году для этого есть три уровня инструментов: гибкая раскладка (Flexbox, Grid, относительные единицы), медиазапросы по экрану и контейнерные запросы по размеру компонента.

Начало: meta viewport

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

Без этой строки мобильный браузер рисует страницу на виртуальном холсте шириной около 980px и уменьшает её, медиазапросы для телефона не срабатывают. Не добавляйте user-scalable=no и maximum-scale=1: они мешают людям увеличивать текст.

Единицы

ЕдиницаОт чего считается
pxфиксированный CSS-пиксель
%от размера containing block (для padding и margin даже по вертикали от ширины)
emот font-size текущего элемента (в самом font-size от родителя)
remот font-size корня html
vw, vh1% ширины и высоты viewport
svh, lvh, dvhвысота viewport с учётом панелей мобильного браузера
cqi, cqw1% размера контейнера (в контейнерных запросах)

Размер шрифта задавайте в rem: если пользователь увеличил базовый шрифт в настройках браузера, всё масштабируется. em удобен для отступов внутри кнопки, которые должны расти вместе с её текстом, но вложенные em накапливаются.

100vh на мобильном равно высоте экрана при скрытой адресной строке, поэтому блок на весь экран вылезает за край. 100svh берёт маленький вариант (панели видны), 100lvh большой, 100dvh меняется на лету. Для экрана-заставки обычно берут min-height: 100svh или 100dvh.

Медиазапросы

.cards { display: grid; gap: 16px; }

@media (width >= 768px) {
  .cards { grid-template-columns: 1fr 1fr; }
}
@media (width >= 1200px) {
  .cards { grid-template-columns: repeat(3, 1fr); }
}

Mobile-first: базовые стили пишутся для узкого экрана, а сверху добавляются min-width (или width >=) условия. Так меньше переопределений, и телефон не грузит лишнее. Синтаксис диапазонов (width >= 768px) и (400px <= width < 800px) работает во всех основных браузерах, классический (min-width: 768px) тоже.

Полезные медиа-фичи кроме ширины:

  • (hover: hover) и (pointer: coarse): есть ли наведение, точный ли указатель. Ховер-эффекты лучше прятать за (hover: hover), на тач-экране они «залипают».
  • (prefers-reduced-motion: reduce): пользователь просит меньше анимаций.
  • (orientation: landscape).

Брейкпоинты выбирайте по контенту (где ломается вёрстка), а не по моделям устройств.

Контейнерные запросы

Медиазапрос знает ширину экрана, но не знает, где лежит компонент. Карточка в узком сайдбаре и та же карточка в широкой ленте при одном экране должны выглядеть по-разному. Для этого контейнерные запросы:

.card-slot { container-type: inline-size; }

.card { display: grid; gap: 12px; }

@container (width >= 420px) {
  .card { grid-template-columns: 160px 1fr; }
}
  • container-type: inline-size объявляет элемент контейнером по ширине. Элемент не может запросить сам себя: правила внутри @container применяются к его потомкам.
  • Контейнеру можно дать имя: container: sidebar / inline-size; и потом @container sidebar (width > 300px).
  • Единицы cqi позволяют размерам зависеть от контейнера: font-size: clamp(1rem, 4cqi, 1.5rem).

Работает во всех основных браузерах с 2023 года. Правило: раскладка страницы на медиазапросах, внутренности переиспользуемых компонентов на контейнерных.

Плавные размеры: clamp, min, max

h1 { font-size: clamp(1.75rem, 1rem + 3vw, 3rem); }
.content { width: min(100% - 32px, 720px); margin-inline: auto; }

clamp(MIN, PREF, MAX) возвращает предпочтительное значение, но не меньше минимума и не больше максимума. Так заголовок растёт вместе с экраном без медиазапросов. Кладите в середину сумму rem + vw, а не чистый vw: иначе текст не реагирует на увеличение шрифта пользователем.

min(100% - 32px, 720px) даёт колонку до 720px с полями по 16px на телефоне.

Картинки

<img
  src="photo-800.jpg"
  srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1600.jpg 1600w"
  sizes="(width >= 900px) 50vw, 100vw"
  width="800" height="600" alt="Кофейня изнутри" loading="lazy">
  • srcset с w перечисляет файлы и их ширину, sizes сообщает, какую ширину картинка займёт на экране. Браузер сам выбирает файл с учётом плотности пикселей.
  • <picture> с <source media> нужен для арт-дирекшна (другой кадр на телефоне) или для форматов (type="image/avif").
  • Атрибуты width и height дают браузеру пропорцию заранее и убирают прыжки вёрстки. Для блоков без картинки то же делает aspect-ratio: 16 / 9.
  • Картинка не вылезет из колонки с max-width: 100%; height: auto.

Логические свойства

margin-inline, padding-block, inset-inline-start, inline-size вместо left/right/width. Они следуют направлению письма, и интерфейс на арабском или иврите (dir="rtl") переворачивается без отдельных стилей.

Частые ошибки

  • Забыть meta viewport.
  • Писать 100vh для полноэкранного блока на мобильном.
  • Шрифт в px или чистом vw: не масштабируется настройками пользователя.
  • Брейкпоинты под конкретные айфоны вместо контента.
  • Картинки без width/height, отсюда сдвиги вёрстки.

Что спросят на собесе

  • Что такое mobile-first и зачем meta viewport?
  • Чем em отличается от rem?
  • Чем контейнерные запросы отличаются от медиазапросов?
  • Как сделать адаптивный размер шрифта без медиазапросов?
  • Как отдать телефону картинку поменьше?

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.