Адаптивная вёрстка — это когда один и тот же сайт удобно выглядит и на телефоне, и на планшете, и на десктопе. Контент не «ломается», шрифты и отступы масштабируются, меню на узком экране может превращаться в гамбургер, а сетки — перестраиваться в одну колонку.
В этом занятии: подход Mobile first, медиа-запросы @media, единицы rem и em, vh/vw, кратко — container queries и адаптивные изображения. В практике — три брейкпоинта, меню-гамбургер и проверка через DevTools.
Mobile first — это когда базовые стили пишутся под маленький экран (мобильный), а затем с помощью медиа-запросов добавляются правила для планшетов и десктопов. Так проще: не нужно «отменять» лишнее на мобильных, и контент по умолчанию доступен именно там, где часто критичен размер и скорость.
Альтернатива — «desktop first»: сначала стили для широкого экрана, потом @media (max-width: ...) для сужения. Оба подхода допустимы; Mobile first часто удобнее, потому что прогрессивное усиление (добавляем, а не убираем) проще поддерживать.
Ниже один и тот же блок. Кнопки имитируют: «только база» (как на мобильном) и «база + дополнения для широкого экрана». Обратите внимание: на «мобильном» меньше padding и размер шрифта.
Медиа-запросы позволяют применять CSS в зависимости от характеристик устройства: ширины экрана, ориентации, плотности пикселей. Синтаксис: @media (условие) { ... }.
Чаще всего используют ширину viewport: @media (min-width: 768px) — «когда ширина не меньше 768px», @media (max-width: 600px) — «когда ширина не больше 600px». Так задают брейкпоинты: от какой ширины менять раскладку (например колонки в ряд, сайдбар сбоку).
Комбинированные запросы — «от и до», то есть в промежутке — на практике используются очень часто. Условия объединяют через and: @media (min-width: 600px) and (max-width: 900px) { ... } — стили применяются только когда ширина от 600px до 900px включительно. Так задают отдельные стили для планшетов между мобильными и десктопом.
Растягивайте или сужайте окно браузера и наблюдайте за блоком ниже: в зависимости от ширины viewport меняются размер текста, отступы и цвет фона. Так работают медиа-запросы в реальной странице.
Медиа-запросы работают и во внешнем файле .css, и внутри блока <style> на странице — браузер применяет их одинаково. Ниже код, который управляет этим блоком:
@media (max-width: 600px) {
#demoMediaBoxLive {
font-size: 0.9rem;
padding: 12px;
background: #e8f0fe;
}
}
@media (min-width: 601px) and (max-width: 900px) {
#demoMediaBoxLive {
font-size: 1rem;
padding: 18px;
background: #cfe2f3;
}
}
@media (min-width: 901px) {
#demoMediaBoxLive {
font-size: 1.1rem;
padding: 24px;
background: #9fc5e8;
}
}
rem — размер относительно корневого элемента (html). Если у html задано font-size: 16px, то 1rem = 16px, 1.5rem = 24px. Меняете один размер в корне — все элементы в rem масштабируются. Удобно для доступности (пользователь меняет базовый шрифт) и для единообразия масштаба по всему сайту.
em — размер относительно font-size текущего элемента (или родителя для свойств вроде margin/padding, в зависимости от свойства). 1em = текущий размер шрифта. Удобно для отступов и размеров, которые должны быть «пропорциональны тексту»: например padding: 0.5em всегда даёт половину высоты строки. Минус — вложенность: у вложенных элементов em множится от своего контекста.
В блоке ниже размеры заданы в em (относительно контейнера). Кнопки меняют font-size у демо-контейнера — текст и отступы в em масштабируются вместе. Так же rem зависит от корня: изменили базу — всё пересчиталось.
Сейчас у контейнера font-size: 18px. Все em пересчитываются от этой базы.
vh — 1% высоты окна браузера (viewport). 100vh — вся высота экрана. vw — 1% ширины окна; 100vw — вся ширина (с учётом полосы прокрутки, поэтому на страницах с вертикальным скроллом иногда предпочитают 100% для ширины).
Удобно для полноэкранных блоков, баннеров «на весь экран», фиксированных шапок по высоте. Минус: на мобильных адресная строка браузера меняет видимую высоту — 100vh может быть больше видимой области. Для точной «высоты экрана» иногда используют dvh (dynamic viewport height) в современных браузерах.
Ниже блок с высотой и шириной в vh/vw. Кнопки задают разные значения — видно, как размер зависит от размера окна (здесь окно — это страница урока; на большом мониторе блок будет больше).
Container queries (контейнерные запросы) — это когда стили зависят не от размера окна, а от размера родительского контейнера. Контейнер задаётся через container-type: inline-size (или size), затем в потомках можно писать @container (min-width: 400px) { ... }. Полезно для компонентов: карточка, сайдбар — перестраиваются в зависимости от того, сколько места им выделили в макете, а не от ширины всего экрана.
Поддержка в современных браузерах хорошая. Используйте для переиспользуемых блоков, которые могут оказаться в узкой колонке или на всю ширину.
Практический пример: меняем ширину контейнера
Ниже блок с container-type: inline-size. Кнопки задают ширину контейнера. Когда ширина ≥ 220px, срабатывает @container (min-width: 220px) — внутренняя раскладка переключается в две колонки и меняется фон. При необходимости можно также уменьшить или увеличить окно браузера — контейнер ограничен шириной страницы.
Ширина контейнера: 180px → одна колонка. Увеличьте кнопкой до 250px или 320px — появится сетка в две колонки и другой фон.
Чтобы изображения не тянули лишний трафик на мобильных и были чёткими на ретине, используют два основных подхода.
srcset и sizes
srcset — список источников и их ширина: srcset="photo-320.jpg 320w, photo-640.jpg 640w, photo-800.jpg 800w". Дескриптор 320w говорит: «этот файл имеет внутреннюю ширину 320 пикселей». Браузер учитывает ширину viewport и плотность пикселей (retina) и выбирает подходящий файл.sizes — подсказка, какой шириной будет отображаться картинка: sizes="(max-width: 600px) 100vw, 50vw" означает: «при ширине экрана до 600px картинка занимает 100% ширины окна, иначе — 50%». Без sizes браузер считает, что изображение на всю ширину (100vw), и может загрузить слишком большой файл.src остаётся fallback для старых браузеров; обычно в него ставят «средний» или самый частый вариант.picture
<picture> даёт полный контроль: несколько <source> с атрибутами media (условие по ширине) или type (формат: image/webp, image/avif). Браузер выбирает первый подходящий source; если ни один не подошёл — используется <img> внутри.В реальной странице выбор источника зависит от ширины окна и плотности пикселей. Нажмите кнопку: в блоке кода ниже будет показано, какой src браузер подставит при узком или широком экране (имитация).
При узком экране браузер подставит photo-320.jpg (320w). Сейчас: узкий.
Mobile first — базовые стили для мобильных, затем медиа-запросы для больших экранов. Медиа-запросы @media (min-width: ...) / max-width задают брейкпоинты. rem — от корня, em — от текущего шрифта; vh/vw — от окна. Container queries — стили от размера контейнера. Адаптивные картинки — srcset, sizes, picture. Не забудьте meta name="viewport" в <head>, иначе медиа-запросы на мобильных могут работать некорректно.
Выберите для каждой единицы подходящее описание.
Подход Mobile first означает:
Чтобы применить стили только когда ширина экрана не меньше 768px, пишут:
Для доступа к практике нужно набрать не менее 80% (минимум 7 из 8 правильных ответов).
1. Mobile first — это…
2. Медиа-запрос @media (max-width: 600px) срабатывает когда…
3. rem зависит от…
4. 100vh — это…
5. Для адаптивных изображений используют…
6. Container queries позволяют применять стили в зависимости от…
7. Мета-тег viewport нужен чтобы…
8. em — это размер относительно…
Сделайте одну HTML-страницу со стилями в <style> (или подключите .css и для проверки скопируйте стили в тот же файл). Выполните:
max-width: 480px, min-width: 768px, min-width: 1024px или свои значения). В каждом брейкпоинте что-то должно меняться: размер шрифта, отступы, количество колонок, видимость блоков.<head> должен быть meta name="viewport" content="width=device-width, initial-scale=1".Проверьте вёрстку через DevTools: режим адаптивного дизайна (Toggle device toolbar), изменение ширины окна — убедитесь, что брейкпоинты и гамбургер работают. Порог зачёта: 70 баллов из 100. Загрузите index.html и нажмите «Проверить».