Урок 10. Адаптивная вёрстка — сайт для телефона и компьютера
На многих сайтах больше половины посетителей приходят с телефонов. Адаптивная вёрстка — это когда одна и та же страница сама перестраивается под ширину экрана: на компьютере — колонки рядом, на телефоне — друг под другом, крупный текст и удобные для пальца кнопки. Отдельная «мобильная версия» сайта для этого не нужна.
Шаг 1. meta viewport
Без этой строки в <head> телефон показывает страницу так, будто у него экран шириной около 980 пикселей, и уменьшает её — всё становится мелким:
<meta name="viewport" content="width=device-width, initial-scale=1">width=device-width — ширина страницы равна ширине экрана, initial-scale=1 — без начального уменьшения. Эта строка нужна на каждой странице. Остальное в адаптивности делает CSS.
Не добавляйте в неё user-scalable=no или maximum-scale=1: они запрещают увеличивать страницу пальцами, а людям со слабым зрением это нужно.
Шаг 2. Резиновые размеры
Главный враг адаптивности — жёсткая ширина в пикселях. Блок width: 1000px на телефоне шириной 390 пикселей вылезет за экран, и страница начнёт прокручиваться вбок.
- Ширина колонки —
max-widthвместоwidth:max-width: 1000pxне больше 1000, но сужается вместе с экраном. - Колонки — в
fr(Grid) илиflex: 1(Flexbox), а не в пикселях. - Шрифты и отступы — в
rem. - Картинки не шире своего блока:
img {
max-width: 100%;
height: auto;
}max-width: 100% не даёт картинке стать шире родителя, height: auto сохраняет пропорции. Эти две строки есть почти в любом CSS. Подробнее — в справке Как сделать адаптивную картинку.
Шаг 3. Медиазапросы
Медиазапрос — блок CSS, который действует только при условии, например при ширине окна не меньше заданной:
.cards {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
}
@media (min-width: 600px) {
.cards {
grid-template-columns: 1fr 1fr;
}
}
@media (min-width: 960px) {
.cards {
grid-template-columns: 1fr 1fr 1fr;
}
}На телефоне карточки идут в один столбец, от 600 пикселей — в два, от 960 — в три. Правила внутри @media просто дописываются к обычным, когда условие выполнено. Поэтому медиазапросы ставят после основных правил: при равной точности побеждает то, что ниже.
min-width: 600px— ширина окна 600 пикселей и больше;max-width: 599px— 599 пикселей и меньше.
Сначала телефон
Удобнее писать стили сначала для узкого экрана, а затем медиазапросами с min-width добавлять колонки для широкого — так и сделано в примере выше. Такой подход называют mobile first. Простой одноколоночный вид работает везде, а сложная раскладка включается, только когда для неё есть место.
Точки перехода (их называют breakpoints) не привязывают к конкретным моделям телефонов. Расширяйте окно и ставьте медиазапрос там, где раскладка начинает выглядеть плохо: строки стали слишком длинными, появилось место для второй колонки.
Пример: страница с боковым меню
Из урока CSS Grid — раскладка «шапка, меню, текст, подвал». На телефоне меню уходит под шапку:
.layout {
display: grid;
grid-template-columns: 1fr;
grid-template-areas:
"head"
"side"
"main"
"foot";
gap: 16px;
}
@media (min-width: 800px) {
.layout {
grid-template-columns: 220px 1fr;
grid-template-areas:
"head head"
"side main"
"foot foot";
}
}
.head { grid-area: head; }
.side { grid-area: side; }
.main { grid-area: main; }
.foot { grid-area: foot; }HTML при этом не меняется — меняется только раскладка.
Меню на узком экране
Меню из пяти-шести ссылок в ряд не помещается на телефоне. Самое простое решение — разрешить перенос:
.menu {
display: flex;
flex-wrap: wrap;
gap: 8px 16px;
}Две цифры в gap — промежуток между строками и между столбцами. Как сделать меню целиком — в справке Как сделать меню на сайте.
Текст и кнопки
- Основной текст — не мельче 16 пикселей (
1rem): на телефоне мелкий шрифт не прочитать. - Длинные строки на большом экране читать тяжело. Ограничьте ширину колонки текста, например
max-width: 70ch(ch— ширина символа «0» шрифта, 70ch — около 70 знаков). - Кнопки и ссылки, по которым нажимают пальцем, — крупные и не вплотную друг к другу. В рекомендациях по доступности (WCAG) удобный размер — от 44 на 44 пикселя.
- Заголовок может плавно уменьшаться вместе с экраном:
font-size: clamp(1.5rem, 5vw, 2.5rem);— не меньше 1.5rem, не больше 2.5rem, а между ними — 5 % ширины окна.
Как проверить
Сузить окно браузера мышью — уже неплохая проверка. Точнее — режим устройства в инструментах разработчика:
- Откройте инструменты разработчика (
F12). - Нажмите
Ctrl+Shift+M— в Chrome, Edge и Firefox включится режим, где можно выбрать ширину экрана или модель телефона. На macOS —Cmd+Shift+Mв Chrome иCmd+Option+Mв Firefox. - Пролистайте страницу на разных ширинах: нет ли прокрутки вбок, всё ли читается, не налезают ли блоки.
В конце обязательно откройте сайт на настоящем телефоне: режим браузера не показывает, как страница ощущается под пальцем.
Частые ошибки
- На телефоне всё мелкое, как на компьютере — нет
<meta name="viewport" …>. - Страница прокручивается вбок — что-то шире экрана: блок или картинка с шириной в пикселях, длинная ссылка без переносов, таблица. Найти виновника помогает инструмент разработчика: выбирайте блоки по очереди и смотрите их ширину.
- Медиазапрос не срабатывает — он стоит выше основного правила и перебит им, или забыты скобки:
@media (min-width: 600px), а не@media min-width: 600px.
Коротко
<meta name="viewport" content="width=device-width, initial-scale=1">— на каждой странице.- Никаких жёстких ширин:
max-width,fr,flex,rem, у картинок —max-width: 100%; height: auto;. - Медиазапрос
@media (min-width: 600px) { … }включает правила от заданной ширины, ставится после основных. - Mobile first: сначала стили для телефона, потом колонки для широких экранов.
- Проверка — режим устройства (
Ctrl+Shift+Mв инструментах разработчика) и настоящий телефон.