Два основных инструмента раскладки в CSS решают разные задачи, и споры «что лучше» обычно возникают там, где их путают. Flexbox работает с одной осью и хорошо раскладывает то, что выстраивается в линию. Grid работает сразу с двумя осями и хорошо раскладывает то, что должно выравниваться по колонкам и строкам. На практике в одном макете живут оба, и вопрос стоит не «что выбрать вообще», а «что взять для этого конкретного блока». Ниже — как мы принимаем такое решение, какие приёмы экономят время и на чём раскладка чаще всего ломается.
Разница в одном предложении
Flexbox распределяет свободное место вдоль одной оси: элементы сами решают, сколько занять, а контейнер задаёт правила выравнивания и переноса. Grid задаёт сетку заранее: вы описываете колонки и строки, а элементы встают в ячейки. Отсюда простое практическое правило: если вам важно, чтобы элементы в разных строках были выровнены между собой по вертикали, нужен Grid. Если важно только распределить их вдоль линии, достаточно Flexbox.
Ещё одно различие полезно помнить при отладке. Во Flexbox размеры считаются от содержимого, поэтому длинный текст в одном элементе меняет ширину соседей. В Grid ширина колонки задана правилом сетки, и содержимое к ней подстраивается. Большая часть «поехавших» блоков объясняется тем, что для задачи с жёстким выравниванием взяли инструмент с гибкими размерами.
Что брать под конкретную задачу
| Задача | Инструмент | Почему так |
|---|---|---|
| Ряд кнопок, меню, набор тегов | Flexbox | Элементы разной ширины в одну линию с переносом |
| Шапка: логотип, меню, кнопка | Flexbox | Распределение по одной оси, крайние элементы прижимаются к краям |
| Каталог карточек | Grid | Ровные колонки и строки, карточки одной высоты в ряду |
| Раскладка страницы целиком | Grid | Колонки и области описываются сразу по двум осям |
| Форма: подписи и поля | Grid | Подписи выравниваются в колонку независимо от длины |
| Внутренность карточки | Flexbox | Вертикальный стек, кнопка прижимается к низу |
| Панель фильтров с переменным числом чипов | Flexbox | Число элементов заранее неизвестно, важен перенос |
| Таблица цен или сравнения | Grid | Значения должны стоять строго друг под другом |
Приёмы, которые экономят время
Автоподбор числа колонок
Комбинация значений repeat, auto-fit и minmax позволяет сетке самой решать, сколько колонок поместится в доступную ширину. Такая сетка перестраивается плавно и не требует отдельной точки перестроения на каждый размер экрана. Для каталогов и списков карточек это основной рабочий вариант: вы задаёте минимальную комфортную ширину карточки, а число колонок считается само.
Разница между auto-fit и auto-fill проявляется, когда элементов мало: первый растягивает существующие карточки на всю ширину, второй оставляет пустые треки. Если единственная карточка в блоке выглядит неестественно широкой — обычно дело именно в этом выборе.
Промежутки вместо отступов
Свойство gap задаёт расстояние между элементами один раз и работает и в Grid, и во Flexbox. Оно избавляет от привычной конструкции «отступ у всех, кроме последнего», а вместе с ней — от правок при изменении порядка элементов. Отступы у самих элементов после этого стоит оставить только там, где они относятся к содержимому, а не к раскладке.
Кнопка, прижатая к низу карточки
Вертикальная flex-колонка плюс автоматический верхний отступ у последнего элемента прижимает кнопку к низу независимо от длины заголовка. В ряду с разной длиной текста кнопки оказываются на одной линии, и ряд карточек перестаёт выглядеть рваным.
Именованные области
В Grid раскладку можно описать именами областей: шапка, боковая колонка, содержимое, подвал. Такая запись читается без разбора цифр, а на мобильной ширине блоки переставляются переопределением одной строки правил, без изменения разметки.
Где они работают вместе
Практически в любом интерфейсе связка выглядит так: страница и сетка карточек — на Grid, содержимое каждой карточки и мелкие горизонтальные группы — на Flexbox. Смешивать их не только можно, но и нужно: элемент грида сам становится flex-контейнером для своего содержимого, и это не создаёт никаких конфликтов.
Обратная ситуация — попытка сделать всё на чём-то одном. Каталог на Flexbox с процентными ширинами держится ровно до тех пор, пока во всех карточках одинаковый текст. Горизонтальное меню на Grid требует пересчёта числа колонок при каждом изменении состава пунктов. И то, и другое работает, но обходится дороже в поддержке.
Частые ошибки
- Фиксированная ширина элемента внутри гибкой сетки. Появляется горизонтальная прокрутка на узких экранах, причём обычно не на том экране, где ошибку допустили.
- Забытая минимальная ширина. По умолчанию элемент не сжимается меньше своего содержимого, поэтому одно длинное слово или неразрывная ссылка растягивают колонку и ломают весь ряд.
- Перестановка блоков средствами раскладки без учёта порядка чтения. Визуально всё верно, но навигация с клавиатуры и программы чтения с экрана идут по порядку в разметке.
- Вложенные обёртки на всякий случай. Половина из них появилась во времена раскладки на плавающих блоках и теперь только мешает: и Grid, и Flexbox управляют прямыми потомками, лишний уровень разрывает эту связь.
- Высота, заданная в пикселях. Текст в реальном контенте почти всегда длиннее, чем в макете, и упирается в границу блока.
- Растягивание элементов по умолчанию там, где это не нужно: картинка в ряду разной высоты неожиданно вытягивается на всю строку.
Порядок чтения и доступность
Обе технологии позволяют менять визуальный порядок элементов, не трогая разметку. Это удобно для мобильной версии, но легко превращается в проблему: фокус при переходе по клавише табуляции движется по разметке, а не по картинке. Если кнопка визуально стоит первой, а в разметке последней, пользователь клавиатуры доберётся до неё в конце.
Наше правило простое: порядок в разметке должен соответствовать смыслу, а раскладка отвечает только за расположение. Небольшие перестановки допустимы, крупные — повод изменить саму структуру страницы.
Как мы проверяем раскладку
- Плавно меняем ширину окна от 320 до 1920 пикселей, а не переключаемся между тремя стандартными размерами: большая часть проблем живёт между точками перестроения.
- Подставляем реальные данные: самое длинное название из базы, отсутствующую картинку, пустой список, один элемент вместо восьми.
- Проверяем блок с увеличенным размером шрифта в браузере — раскладка не должна рассыпаться.
- Проходим страницу с клавиатуры и сверяем порядок фокуса с визуальным порядком.
- Смотрим страницу на реальном телефоне: эмулятор не показывает поведение адресной строки и инерционной прокрутки.
Большинство дефектов раскладки проявляется именно на крайних случаях, а не на аккуратном демонстрационном контенте. Поэтому проверку на реальных данных мы делаем до передачи страницы в вёрстку разделов, а не после того, как её заполнили содержимым.
Если нужна вёрстка, которая не рассыпается на реальных данных, или разбор уже существующей раскладки, мы можем взять это на себя. Посмотрите, как устроена наша разработка сайтов, и напишите — обсудим задачу и предложим порядок работ.











