Flexbox и grid
Что это такое
Flexbox и grid — две системы раскладки в CSS. Flexbox распределяет элементы вдоль одной оси, строки или столбца, и подходит, когда размеры задаёт содержимое. Grid размещает элементы в двумерной структуре строк и столбцов; к нему прибегают, когда положение содержимого должна задавать структура.
Почему это важно
До них раскладка страницы означала обтекания, абсолютное позиционирование и хаки clearfix, а каждая раскладка была переговорами между элементами, которые друг о друге не знали. Flexbox и grid перенесли выравнивание, отступы и распределение в контейнер, где их можно описать один раз. Поэтому адаптивный ряд карточек, прижатый к низу подвал и центрированный диалог теперь три коротких правила, а не три хрупких трюка. Однако выбрать из двух — почти весь навык: неподходящая всё равно работает, но лишь после борьбы.
Ключевые идеи
Flexbox — одна ось, grid — две
Flex-контейнер раскладывает потомков вдоль одного направления: элементы могут расти, заполняя место, сжиматься при тесноте и выравниваться друг относительно друга. Grid-контейнер сначала задаёт дорожки и размещает элементы по ним. Если вы ловите себя на трёхуровневой вложенности flex-контейнеров ради двумерной раскладки, grid — ответ поспокойнее.
.toolbar {
display: flex;
align-items: center;
gap: 0.5rem;
}
.layout {
display: grid;
grid-template-columns: 16rem 1fr;
gap: 1.5rem;
}
Пространство — свойство контейнера
gap заменяет хаки с margin, которыми раньше раздвигали элементы, не добавляя места снаружи. justify-content и align-items размещают элементы по двум осям, а в grid те же имена применяются к дорожкам через justify-content и собственный justify-self элемента; именно явное называние оси — главная и поперечная в flex, строки и столбцы в grid — и делает свойства читаемыми.
Пусть решает содержимое или структура
flex: 2 и grid-template-columns: 1fr 2fr оба выражают пропорцию, но расходятся, когда содержимое велико. Flex-элементы могут отказаться сжиматься ниже своего содержимого, если не задать min-width: 0, а дорожки grid с 1fr привязаны к дорожке и могут переполниться. Именно здесь и проходит настоящее проектное решение: решить, какое поведение вам нужно.
Повторяйте и задавайте дорожки по содержимому
Grid умеет порождать дорожки по правилу: repeat(auto-fit, minmax(16rem, 1fr)) даёт столько равных столбцов, сколько помещается выше минимальной ширины, и заменяет стопку точек перелома одной строкой.
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
gap: 1rem;
}
Вложенные контейнеры нормальны, глубокая вложенность — нет
Элемент grid может быть flex-контейнером, и наоборот; так и строятся настоящие раскладки. Однако глубина — уже запах: если для размещения одного элемента нужны четыре уровня, внешняя структура, вероятно, делает работу, с которой справился бы один grid.
Практика
Постройте ряд карточек, который переносится без точек перелома
Разложите восемь карточек через grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)) и gap. Медленно меняйте ширину окна.
Готово, когда: карточки переносятся на ширине, выведенной из минимума столбца, а не из написанной вами точки перелома, и ни одна карточка не становится уже 16rem.
Отцентрируйте диалог сначала flex, потом grid
Постройте модальное окно по центру полноэкранной подложки: один раз центрированием через flex, другой раз размещением через grid. Сравните число правил.
Готово, когда: обе версии центрируют диалог точно, и вы можете сказать, какую оставили бы в кодовой базе и почему.
Частые ошибки
- Flexbox для двумерной раскладки — вложенные flex-контейнеры накапливаются, и отступы становятся угадыванием; исправить: берите grid для строк и столбцов, а flex — внутри ячейки.
- Забытый
min-width: 0у flex-элемента — длинное слово мешает элементу сжаться, и ряд переполняется; исправить: разрешите элементу сжиматься или перенесите текст. - Починка выравнивания полями — смещения ломаются, как только элемент меняет размер; исправить: используйте
align-items,justify-contentиgapу контейнера. flex: 1на всём подряд — каждый элемент борется за одну и ту же долю, и самое мелкое содержимое проигрывает; исправить: задайте flex-значение только тем элементам, которые должны растягиваться.- Жёсткая сетка под самый широкий экран — узкие экраны уходят в боковую прокрутку; исправить: используйте
auto-fitсminmaxили дайте дорожкам схлопываться.
Что читать дальше
- Каскад и блочная модель (02-frontend/05-css/01-cascade-and-box-model) —
box-sizing,gapи размеры дорожек предполагают, что вы знаете, откуда берутся измерения элемента. - Медиа- и контейнерные запросы (02-frontend/05-css/03-media-and-container-queries) — как та же раскладка адаптируется при смене окна или родителя.
- Макетирование и сеточные системы (03-design-ux/30-layout-grid-systems) — словарь со стороны дизайна для решений, которые вы здесь принимаете.