Когда вы только начинаете верстать, главная головная боль — не подобрать шрифт или цвет, а расставить блоки так, чтобы они не разбегались. Как сделать меню в одну строку? Как прижать кнопку к правому краю? Как собрать карточки товаров в аккуратную сетку? Для всего этого в современном CSS есть два мощных инструмента: Flexbox и CSS Grid. Без них сегодня не обходится ни один макет, и если вы поймёте их логику, вёрстка перестанет быть магией.
Я занимаюсь сайтами для малого бизнеса с 2015 года, и на своём опыте скажу: новички часто пытаются решить эти задачи старыми методами — float, display: inline-block, кучей margin. Это работает, но код становится хрупким и неудобным. Flexbox и Grid дают контроль и предсказуемость. Давайте разберёмся, как они устроены и когда какой использовать.
Что такое Flexbox и Grid простыми словами
Flexbox — это инструмент для раскладки элементов в одной плоскости: либо по горизонтали, либо по вертикали. Представьте, что вы выкладываете кнопки в ряд в шапке сайта или иконки в меню — вам нужно, чтобы они шли друг за другом и красиво распределялись. Flexbox для этого и создан.
Grid же работает сразу в двух измерениях: строки и колонки. Это как таблица, но гораздо гибче. С его помощью вы можете разбить страницу на области: шапка, сайдбар, контент, подвал — и управлять их размерами.
Простая аналогия: Flexbox — это лента, вдоль которой выстраиваются элементы; Grid — это сетка с ячейками. Запомните: Flexbox для одного направления, Grid для двух. Когда я только начинал, то пытался сделать сетку карточек на Flexbox — это возможно, но приходится городить костыли с flex-wrap и высчитывать ширину. Как только перешёл на Grid, жизнь стала проще.
Когда использовать Flexbox, а когда Grid
Новички часто влюбляются в один инструмент и пытаются применить его везде. Видел, как человек упорно верстал всю страницу на Flexbox, включая сложную сетку с разными высотами — код получался громоздким и ломался на мобильных. Лучше сразу выбрать подходящий.
| Задача | Лучше использовать | Почему |
|---|---|---|
| Меню в шапке | Flexbox | Элементы идут в строку и легко выравниваются |
| Кнопка рядом с иконкой | Flexbox | Нужно распределение в одной линии |
| Карточки товаров в 3 колонки | Grid | Удобно задать сетку |
| Сайт с контентом и сайдбаром | Grid | Есть строки и колонки |
| Центровка блока по горизонтали и вертикали | Flexbox или Grid | Оба подходят, но Flexbox чаще проще |
| Сложная сетка из блоков разного размера | Grid | Grid лучше управляет областями |
Если коротко: для одной оси — Flexbox, для двух осей — Grid. Это не железное правило, но для новичка оно отлично работает.
Основы Flexbox
Как включить Flexbox
Чтобы превратить обычный блок в flex-контейнер, достаточно одной строки:
.container {
display: flex;
}
После этого все прямые дочерние элементы внутри .container становятся flex-элементами и начинают подчиняться правилам Flexbox. Важно: flex-контейнером становится именно родитель, а не сами элементы. Частая ошибка — написать display: flex на кнопке, которую нужно выровнять, а не на её обёртке.
Главная идея Flexbox
В основе Flexbox лежат две оси: главная (main axis) и поперечная (cross axis). По умолчанию главная ось направлена слева направо (как строка текста), а поперечная — сверху вниз. Если вы меняете flex-direction на column, оси меняются местами: главная становится вертикальной. Понимание осей — ключ к тому, чтобы не путаться в свойствах justify-content и align-items. Первое работает по главной оси, второе — по поперечной.
Самые важные свойства Flexbox
justify-content
Это свойство управляет распределением элементов вдоль главной оси. Например, если у вас меню из трёх ссылок, вы можете прижать их к левому краю (flex-start), к правому (flex-end), отцентрировать (center) или растянуть так, чтобы первая и последняя были по краям, а между ними равные промежутки (space-between). На практике space-between часто используют для шапок: логотип слева, меню справа, а между ними пустота. Но будьте осторожны: если элементов мало, расстояние может выглядеть неестественно большим. Я обычно комбинирую с gap для более контролируемых отступов.
Примеры:
.container {
display: flex;
justify-content: center; /* или flex-start, flex-end, space-between, space-around, space-evenly */
}
align-items
Выравнивание по поперечной оси. Если главная ось горизонтальна, то align-items управляет положением элементов по вертикали. Значение center позволяет легко выровнять кнопки и текст по середине контейнера, что раньше требовало танцев с бубном. stretch (по умолчанию) растягивает элементы на всю высоту контейнера — удобно для колонок одинаковой высоты. baseline выравнивает элементы по базовой линии текста, полезно, когда у вас иконки разного размера рядом с текстом.
.container {
display: flex;
align-items: center;
}
gap
Раньше, чтобы задать расстояние между flex-элементами, приходилось добавлять margin каждому элементу и убирать лишний отступ у последнего. gap решает эту проблему элегантно: gap: 20px; создаёт промежуток в 20px между всеми элементами, не затрагивая края контейнера. Это свойство появилось позже, но сейчас поддерживается везде. Я использую его почти всегда вместо margin.
.container {
display: flex;
gap: 20px;
}
flex-direction
Определяет направление главной оси. По умолчанию row — элементы идут слева направо. column — сверху вниз, как в колонке. row-reverse и column-reverse меняют порядок на обратный. Зачем это нужно? Например, на мобильной версии вы можете захотеть поменять местами блоки без изменения HTML. Но не злоупотребляйте: обратный порядок может запутать читалку для скринридеров.
.container {
display: flex;
flex-direction: row; /* column, row-reverse, column-reverse */
}
flex-wrap
По умолчанию flex-элементы пытаются уместиться в одну линию, даже если им не хватает места. flex-wrap: wrap; разрешает перенос на следующую строку. Это обязательное свойство для адаптивных карточек: когда экран сужается, карточки перескакивают вниз, а не сжимаются в лепёшку. Часто сочетаю с gap, чтобы перенесённые элементы не слипались.
.container {
display: flex;
flex-wrap: wrap;
}
Базовые свойства самих элементов
Дочерние элементы тоже можно настраивать. flex-grow определяет, какую долю свободного пространства элемент может занять. Если всем элементам задать flex-grow: 1, они равномерно заполнят контейнер. flex-shrink управляет сжатием при нехватке места. flex-basis задаёт начальный размер перед распределением остатков. На практике я редко использую их по отдельности — гораздо удобнее краткая запись flex: 1 1 0 (или просто flex: 1). Она говорит: «можешь расти, можешь сжиматься, базовый размер 0». Это стандартный паттерн для равных колонок.
.item {
flex: 1;
}
Основы CSS Grid
Как включить Grid
Аналогично Flexbox: display: grid; на контейнере. После этого можно задавать сетку из строк и колонок.
.container {
display: grid;
}
Главная идея Grid
Grid работает в двух измерениях одновременно. Вы определяете структуру сетки — сколько колонок, какой ширины, сколько строк, какой высоты — и затем размещаете элементы по ячейкам. Это похоже на вёрстку таблицами, но без ограничений и с полным контролем. Grid позволяет создавать сложные макеты, которые раньше требовали вложенных блоков и хаков.
Самые важные свойства Grid
grid-template-columns
Задаёт количество и ширину колонок. Можно указать конкретные значения: 200px 300px 200px — три колонки с фиксированной шириной. Но чаще используют гибкие единицы fr (fraction). repeat(3, 1fr) создаст три равные колонки, которые займут всё доступное пространство. repeat(auto-fill, minmax(250px, 1fr)) — магия адаптивности: колонки будут автоматически добавляться, пока помещаются, и каждая будет не меньше 250px, но может растягиваться.
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
grid-template-rows
Определяет высоту строк. Часто строки задают неявно: если вы не указываете grid-template-rows, Grid сам создаст строки нужной высоты под содержимое. Но для точного контроля можно задать, например, grid-template-rows: 100px auto 100px; — шапка, контент, подвал. auto подстроится под содержимое.
.container {
display: grid;
grid-template-rows: 100px auto 100px;
}
gap
Работает так же, как во Flexbox: задаёт промежутки между ячейками. Можно указать два значения: gap: 20px 10px; — отступы между строками 20px, между колонками 10px.
.container {
display: grid;
gap: 20px;
}
fr
Единица fr — это доля свободного пространства. Если у вас grid-template-columns: 1fr 2fr, то вторая колонка будет вдвое шире первой. Это очень удобно для пропорциональных раскладок. В отличие от процентов, fr учитывает gap и не вызывает переполнения.
.container {
display: grid;
grid-template-columns: 1fr 2fr;
}
Как размещать элементы в Grid
По умолчанию элементы заполняют ячейки по порядку. Но можно явно указать, какой элемент сколько ячеек занимает. Для этого используются свойства grid-column и grid-row. Сетка Grid состоит из линий (между колонками и строками), пронумерованных начиная с 1. grid-column: 1 / 3 означает «от первой линии до третьей», то есть занять две колонки. grid-row: 2 / 4 — занять строки со второй по четвёртую. Это позволяет создавать раскладки, где, например, карточка растягивается на две колонки или блок занимает несколько строк. Поначалу нумерация линий может сбивать с толку, но после пары экспериментов становится интуитивно понятно.
.item {
grid-column: 1 / 3;
grid-row: 2 / 4;
}
Удобный способ создать адаптивную сетку
Один из самых полезных паттернов:
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
}
Он говорит: «создавай столько колонок, сколько влезет, но каждая должна быть не уже 280px и может растягиваться, чтобы занять свободное место». Это идеально для карточек товаров, статей, портфолио. Без медиазапросов сетка сама перестраивается при изменении ширины экрана. Я часто использую этот приём на сайтах малого бизнеса, где заказчик не хочет закладывать бюджет на сложную адаптивную вёрстку.
Простые примеры использования
Пример 1. Меню в шапке через Flexbox
.menu {
display: flex;
gap: 20px;
align-items: center;
list-style: none;
padding: 0;
}
Типичное меню: несколько ссылок в ряд. Flexbox здесь идеален: display: flex на контейнере, gap: 20px для отступов, align-items: center чтобы выровнять по вертикали. Никаких float, никаких лишних обёрток. Если нужно прижать логотип слева, а меню справа, можно добавить justify-content: space-between и два дочерних блока.
Пример 2. Карточки в сетке через Grid
.cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
Сетка из трёх карточек товаров. Всё просто. Карточки сами распределятся равномерно. Если нужно адаптивности, меняем на repeat(auto-fit, minmax(250px, 1fr)) — и на мобильных они перестроятся в одну колонку.
Пример 3. Центровка блока
Через Flexbox:
.parent {
display: flex;
justify-content: center;
align-items: center;
}
Через Grid:
.parent {
display: grid;
place-items: center;
}
Центрировать блок по горизонтали и вертикали — вечная задача. Flexbox: display: flex; justify-content: center; align-items: center; на родителе. Grid: display: grid; place-items: center;. Оба варианта работают, но place-items: center — это краткая запись для align-items и justify-items в Grid, и она очень удобна для быстрой центровки одного элемента. Я часто использую Grid для центровки попапов или лоадеров.
Типичные ошибки новичков
1. Путают контейнер и элемент
Помню, как сам в начале писал display: flex на элементе, который хотел подвинуть, и удивлялся, почему ничего не работает. Flex и Grid применяются к родителю. Если нужно сдвинуть конкретный блок, возможно, вам нужен margin: auto внутри flex-контейнера или позиционирование.
2. Пытаются одновременно применить всё подряд
Новички часто копируют набор свойств из туториала, не понимая, что каждое из них делает. В итоге макет ломается, а причина неясна. Мой совет: добавляйте свойства по одному и сразу смотрите в инспекторе браузера, как меняется раскладка.
3. Используют space-between везде
Да, это удобно, но если у вас два элемента, они разлетятся по краям, а середина останется пустой. Лучше комбинировать с gap и margin-left: auto для точечного прижатия.
4. Делают сетку через flex там, где нужен grid
Я видел проекты, где карточки товаров верстали на Flexbox с flex-wrap и ручным расчётом ширины через calc(). Это работало, но стоило добавить карточку другой высоты — и ряд ломался. Grid решает это элегантно.
5. Не учитывают мобильные экраны
Заказчик смотрит на десктопе — всё красиво. Открывает на телефоне — блоки наползают друг на друга. Всегда проверяйте адаптивность. Минимальный набор: flex-wrap: wrap для Flexbox, auto-fit/minmax для Grid, и медиазапросы для критичных изменений.
Как понять, что выбрать в реальной задаче
Перед тем как писать код, я всегда задаю себе три вопроса. Они помогают быстро определиться с инструментом.
- Элементы должны идти в одну линию или в сетку?
- Нужна ли только горизонтальная логика или ещё и вертикальная?
- Должны ли блоки автоматически переноситься при уменьшении ширины экрана?
Если отвечаете:
- «в одну линию» — берите Flexbox;
- «в сетку» — берите Grid;
- «нужно и то и другое» — чаще всего Grid для общего каркаса, Flexbox для внутренних блоков.
Это рабочая схема, которой пользуются многие верстальщики на практике.
Мини-шпаргалка по свойствам
Flexbox
display: flex— включить Flexbox;flex-direction— направление;justify-content— распределение по главной оси;align-items— выравнивание по поперечной оси;gap— расстояние между элементами;flex-wrap— перенос строк;flex: 1— удобное распределение места (мастхэв для равных колонок).
Grid
display: grid— включить Grid;grid-template-columns— колонки;grid-template-rows— строки;gap— расстояние между ячейками;fr— доля доступного пространства;repeat()— повтор шаблона;minmax()— минимальный и максимальный размер;grid-columnиgrid-row— размещение элементов.
Практический чек-лист перед версткой
- Определите, что вы строите: линию или сетку. Не хватайтесь сразу за код, набросайте на бумаге или в уме структуру.
- Начинайте с
display: flexилиdisplay: grid. - Сначала задайте общую структуру, потом отступы.
- Используйте
gapвместо лишнихmargin— это сэкономит вам правки в будущем. - Проверяйте макет на мобильной ширине, даже если заказчик не просил адаптив — базовую пригодность для телефона обеспечить легко.
- Не усложняйте код, если задачу можно решить проще.
- Для внутренних элементов карточек используйте Flexbox, даже если сама сетка сделана на Grid — так вы сохраните гибкость.
Часто задаваемые вопросы
Можно ли заменить Flexbox Grid’ом?
Технически да, но это как забивать гвозди микроскопом. Для линейных блоков Flexbox проще и читаемее. Я обычно использую Grid для крупных макетов, а Flexbox для внутренних выравниваний.
Что учить первым: Flexbox или Grid?
Flexbox. Он интуитивно понятнее и сразу даёт результат: сделали меню, выровняли кнопки. Grid осваивается чуть сложнее, но после Flexbox идёт легче.
Почему gap лучше, чем margin между элементами?
Потому что gap не создаёт отступов по краям контейнера, и вам не нужно обнулять последний margin. Код чище, меньше сюрпризов при адаптации.
Нужно ли знать оба инструмента?
Обязательно. В реальных проектах они работают в паре. Например, страница свёрстана на Grid, а внутри карточки товара Flexbox выравнивает цену и кнопку.
Что чаще используют в современных сайтах?
Оба повсеместно. Откройте любой сайт — в инспекторе вы увидите и display: flex, и display: grid. Это стандарт.
Вывод
Flexbox и CSS Grid — не конкуренты, а два инструмента, которые закрывают разные задачи. Flexbox хорош для одномерных раскладок: меню, строки, выравнивание. Grid — для двумерных сеток: макеты страниц, карточки товаров, галереи. Если запомнить простое правило — «Flexbox для оси, Grid для сетки» — вёрстка станет логичной и предсказуемой. Начинайте с малого: сверстайте меню, потом сетку карточек, поэкспериментируйте с адаптивом. Чем больше реальных примеров вы сделаете, тем быстрее научитесь видеть структуру макета ещё до написания кода. И не бойтесь ошибаться — инспектор браузера ваш лучший друг.
