Адаптивная вёрстка
Зачем это нужно
Больше половины людей открывают сайты с телефона. Экран телефона — 360–430 пикселей в ширину, планшета — около 800, ноутбука — 1300 и больше. Адаптивная вёрстка — когда одна и та же страница удобно выглядит на любом из них: на компьютере три колонки, на телефоне одна, меню превращается в кнопку. Google даже ставит неадаптивные сайты ниже в поиске.
Мета-тег viewport
Без него телефон делает вид, что у него экран 980px, и показывает сайт мелко, как на компьютере.
Поэтому в <head> каждой страницы пишут:
<meta name="viewport" content="width=device-width, initial-scale=1">
Это значит: «ширина страницы = ширина экрана устройства, масштаб 1:1». Без этой строки медиазапросы на телефоне не сработают как надо.
Относительные единицы
Пиксели (px) — жёсткая единица: 300px — всегда 300px, даже на экране шириной 320px.
Поэтому в адаптивной вёрстке часто используют относительные:
| Единица | От чего считается |
|---|---|
% |
от размера родителя |
em |
от размера шрифта этого элемента |
rem |
от размера шрифта корня (html), обычно 16px |
vw |
1% ширины окна (viewport width) |
vh |
1% высоты окна |
html { font-size: 16px; }
h1 { font-size: 2rem; } /* 32px */
.btn { padding: 0.5em 1em; } /* отступы растут вместе со шрифтом кнопки */
.hero { height: 100vh; } /* баннер на весь экран */
.col { width: 50%; } /* половина родителя */
Результат: заголовок 32px; у кнопки с крупным шрифтом отступы сами больше; баннер ровно в высоту окна.
rem удобен для шрифтов: если пользователь в настройках браузера увеличил шрифт — вся страница
аккуратно увеличится.
Гибкие картинки
Картинка 800px в колонке шириной 300px вылезет за край. Лечится двумя строками:
img {
max-width: 100%;
height: auto;
}
Результат: картинка никогда не шире родителя; на узком экране она уменьшается, сохраняя пропорции.
Медиазапросы
Медиазапрос — правила CSS, которые работают только при условии:
.menu { display: none; }
@media (min-width: 600px) {
.menu { display: flex; }
}
Результат: на экранах уже 600px меню скрыто, от 600px и шире — показано.
min-width: 600px— «ширина окна от 600px»;max-width: 599px— «ширина окна до 599px».
Внутри @media { … } — обычные правила CSS. Они перекрывают такие же правила выше по каскаду
(медиазапросы пишут после основных правил).
Mobile first
Есть два подхода:
- mobile first (сначала телефон): основные правила — для узкого экрана, а медиазапросы
min-widthдобавляют колонки на широких; - desktop first: наоборот, основа — для компьютера, а
max-widthупрощает для телефона.
Сейчас принято mobile first: на телефоне сайт простой и быстрый, а сложности добавляются там, где есть место.
.grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 600px) {
.grid { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 1000px) {
.grid { grid-template-columns: 1fr 1fr 1fr 1fr; }
}
Результат: на телефоне одна колонка, на планшете две, на большом экране четыре.
Типичные точки перелома (breakpoints): 600px (большой телефон/планшет), 900px (планшет/ноутбук), 1200px (большой экран). Но лучше ставить их там, где твоей вёрстке становится тесно.
Как это проверить
В браузере нажми F12 и значок телефона («Toggle device toolbar») — можно выбрать iPhone или задать любую ширину и посмотреть, как перестраивается страница. Или просто сужай окно мышкой.
Как это работает внутри
При каждом изменении размера окна браузер заново проверяет условия всех медиазапросов. Правила подходящих запросов участвуют в каскаде, неподходящих — будто их нет. Поэтому при повороте телефона вёрстка перестраивается мгновенно.
Частые ошибки
- Нет мета-тега viewport. На телефоне сайт мелкий, медиазапросы «не работают».
- Медиазапрос выше основного правила. Основное правило ниже перекроет его. Пиши
@mediaв конце. - Порядок
min-widthнаоборот. Если 900px идёт раньше 600px, на широком экране победит правило для 600px. - Фиксированная ширина в px.
width: 1000px— на телефоне появится горизонтальная прокрутка. Используйmax-width: 1000pxи проценты. - Пробел в условии.
@media (min-width:600 px)— между числом иpxпробела быть не должно.
Шпаргалка
| Код | Что делает |
|---|---|
<meta name="viewport" content="width=device-width, initial-scale=1"> |
нормальный масштаб на телефоне |
%, em, rem, vw, vh |
относительные единицы |
img { max-width: 100%; height: auto; } |
гибкие картинки |
@media (min-width: 600px) { … } |
правила от 600px и шире |
@media (max-width: 599px) { … } |
правила до 599px |
| mobile first | основа — для телефона, min-width по возрастанию |