Flexbox и CSS Grid
Две главные технологии раскладки. Flexbox растягивает элементы один за другим, а Grid строит сетку из строк и колонок.
Flexbox: выравнивание одного измерения
Flexbox отлично подходит для меню, строк кнопок, карточек в ряд. Контейнеру задаём display: flex — и его дети выстраиваются в линию.
.nav-row {
display: flex;
justify-content: space-between; /* основная ось */
align-items: center; /* поперечная ось */
gap: 12px;
}
Свойства для родителя:
justify-content— выравнивание по главной оси:flex-start,center,space-between,space-around;align-items— по поперечной оси:stretch,center,flex-start;flex-wrap: wrap— разрешить перенос на новую строку;gap— расстояние между элементами.
Для детей:
.card { flex: 1; } /* растёт и занимает место */
.side { flex: 0 0 200px; } /* фиксированная ширина */
.grow { flex-grow: 2; } /* слайдер роста */
justify-content: center + align-items: center на display:flex-контейнере — самый быстрый способ отцентрировать блок по вертикали и горизонтали.CSS Grid: сетка двух измерений
Grid создаёт «шахматку»: задаём колонки и строки — элементы раскладываются автоматически.
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
Полезные приёмы:
.layout {
display: grid;
grid-template-columns: 200px 1fr; /* боковая + контент */
grid-template-rows: auto auto;
}
.area-header { grid-column: 1 / -1; } /* на всю ширину */
.item { grid-row: 1 / 3; } /* через 2 строки */
.area { grid-area: 2 / 2 / 3 / 3; } /* строка/колонка */
Адаптивность через media queries
Сетка подстраивается под ширину экрана с помощью @media:
.grid { grid-template-columns: 1fr; }
@media (min-width: 768px) {
.grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
.grid { grid-template-columns: repeat(4, 1fr); }
}
min-width-брейкпоинты по мере увеличения. Так стилей меньше и они проще.Когда что выбирать
| Ситуация | Инструмент |
|---|---|
| Меню, кнопки, карточки в ряд | Flexbox |
| Галерея, плитка, сетка товаров | Grid |
| Шапка + сайдбар + контент | Grid |
| Что-то отцентрировать | Flexbox |
flex-direction и направление осей
По умолчанию Flexbox раскладывает элементы слева направо (горизонтальная «главная ось»). Ось легко повернуть:
.row { flex-direction: row; } /* слева направо (по умолчанию) */
.column { flex-direction: column; } /* сверху вниз */
.rev { flex-direction: row-reverse; } /* справа налево */
justify-content теперь работает вертикально, а align-items — горизонтально. Полезный трюк для вертикального центрирования.flex-wrap и свободное место
Если детей много, они сжимаются. Включите перенос flex-wrap: wrap — и всё, что не влезло, уйдёт на новую строку:
.tools {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.tool { flex: 0 0 150px; } /* 0 0 = не растягивается и не сжимается, базовая 150px */
flex: 1 1 0 — «расти на равных»; flex: 0 0 auto — «по своему размеру»; flex: 1 — удобное сокращение «расти и занимать равную долю».grid-template-areas
Самый читаемый способ описать макет — нарисовать его строками-именами. Каждая строка кавычек = ряд сетки:
.layout {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
gap: 12px;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer { grid-area: footer; }
. в схеме означает «пустая ячейка». Имена нельзя повторять в несмежных ячейках — сетка просто не соберётся.auto-fit / auto-fill и minmax()
Сетка может сама решать, сколько помещается колонок, если использовать авто-повтор вместе с минимальной и максимальной шириной:
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 16px;
}
Это значит: минимум колонки 220px, максимум — 1fr. Сколько поместится на экране, столько и будет, без media queries.
auto-fill заполняет сетку «пустышками» до конца строки, auto-fit — растягивает существующие колонки. Итоговое поведение видно наглядно, но для карточек почти всегда выбирают auto-fit.order: расстановка по смыслу
Визуальный порядок элементов можно менять без перестановки в HTML. Свойство order работает и во Flexbox, и в Grid:
.author { order: 1; } /* покажется первым */
.content { order: 2; }
.comments { order: 3; }
order: порядок табуляции с клавиатуры остаётся HTML-ным. Если важна доступность, сохраняйте смысловой порядок в разметке.space-evenly и распределение места
У justify-content три близнеца по распределению «воздуха»: space-between (по краям впритык), space-around (зазоры с боков) и space-evenly (равные отступы везде):
.row {
display: flex;
justify-content: space-evenly; /* все промежутки строго равны */
justify-content: space-around; /* у краёв половинный зазор */
justify-content: space-between; /* крайние прижаты к границам */
}
align-content: строки и переносы
Когда элементов много и родитель переносит их на новые строки, за вертикальное распределение этих строк отвечает align-content:
.tags {
display: flex;
flex-wrap: wrap;
align-content: flex-start; /* строки сверху */
align-content: center; /* по центру между рядами */
align-content: flex-end; /* прижато вниз */
gap: 8px;
}
align-items — внутри одного ряда, align-content — между рядами.grid-auto-flow: dense и мозаика
Если элемент не влезает в ячейку, Grid сделает «дыру». Флаг dense заполняет дыры последующими элементами — получается мозаика без пустот:
.mosaic {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: dense; /* дыры добиваются элементами позже */
gap: 10px;
}
.wide { grid-column: span 2; } /* на две колонки */
.tall { grid-row: span 2; } /* на две строки */
dense меняет визуальный порядок элементов. Для галерей, где порядок не критичен, — идеально.Flexbox: margin-left: auto
Внутри flex-контейнера margin: auto поглощает лишнее пространство и прижимает элемент к противоположной стороне:
.nav { display: flex; gap: 12px; }
.spacer { margin-left: auto; } /* всё, что правее, уедет вправо */
justify-content: space-between на родителе и margin-left: auto на конкретном ребёнке. Второй точнее, когда групп элементов несколько.Связка Grid + Flex: карточка
Реальные макеты почти всегда сетка снаружи и flex внутри карточки:
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 20px;
}
.card {
display: flex;
flex-direction: column; /* тело в столбик */
}
.card .btn {
margin-top: auto; /* кнопка прижата к низу */
}
margin-top: auto внутри flex-колонки опускает дочерний блок к нижнему краю независимо от длины контента выше.Оси на практике
Главная ось — куда смотрят элементы, поперечная — им навстречу:
.row {
display: flex;
flex-direction: row; /* главная ось: слева направо */
justify-content: center; /* по главной оси */
align-items: center; /* по поперечной оси */
}
flex-direction меняет и место «главное»: при column главная ось — вертикаль, и justify-content двигает блоки вверх-вниз.flex-flow: направление + перенос
Одно свойство объединяет направление и разрешение переноса:
.cards {
display: flex;
flex-flow: row wrap; /* строка · можно переноситься */
}
flex: универсальная запись
Три числа: рост — сужение — базис:
.item {
flex: 1 1 200px; /* растёт · может ужаться · идеал 200px */
}
flex: 1 равняется flex: 1 1 0%. Это «расти поровну» — самый частый рецепт.flex-basis 0 — равные колонки
Если базис нулевой, ширина зависит только от коэффициента роста:
.col { flex: 1 1 0%; } /* все одинаковой ширины */
.col--wide { flex: 2; } /* в два раза шире соседей */
align-content: ряды внутри
Когда строк несколько, распределять их помогает align-content:
.grid-lite {
display: flex;
flex-wrap: wrap;
align-content: space-between; /* ряды: растянуты по высоте */
}
Фиксированный сайдбар
Не дайте боковой панели сжиматься, контенту — расти:
.layout {
display: flex;
gap: 16px;
}
.content { flex: 1; } /* забирает свободное */
.aside { flex: 0 0 240px; } /* зафиксирован 240px */
Иконка в квадрате
Любой блок можно центрировать целиком, без пиксельных отступов:
.icon-box {
display: flex;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
}
Порядок: order
order переставляет детей без правки HTML:
.item-1 { order: 3; }
.item-2 { order: 1; } /* будет первым */
.item-3 { order: 2; }
order. Меняйте порядок в HTML, если важен порядок чтения.Футер прижат к низу
Классика flexbox: контент тянется, футер держится у нижней кромки:
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main { flex: 1; } /* занимает свободное место */
footer { flex: 0 0 auto; }
gap в колонках
Промежуток действует и по направлениям — в столбиках то же самое:
.stack {
display: flex;
flex-direction: column;
gap: 12px; /* равные промежутки между абзацами */
}
Почему «схлопывается»?
Длинный текст в flex ряду внезапно вылезает. Частый виновник — контент:
.cut-text {
min-width: 0; /* позволяем содержимому сжиматься */
overflow-wrap: anywhere;
}
min-width: auto, который не даёт сжаться втройне. Укажите min-width: 0 — и текст перенесётся по словам.Инпут + кнопка в один ряд
Классика верстки поиска: поле тянется, кнопка фиксированной ширины:
.search { display: flex; gap: 8px; }
.search input { flex: 1; min-width: 0; }
.search button { flex: 0 0 auto; }
Тренировка
- Соберите строку меню из 4 ссылок через Flexbox с
justify-content: space-between. - Сделайте галерею из 6 фото с
repeat(3, 1fr). - На узком экране превратите галерею в
1frчерез media query. - Попробуйте «липкий» сайдбар:
position: sticky; top: 20px.