Flexbox и Grid
| Тип | модули раскладки CSS |
|---|---|
| Flexbox | CSS Flexible Box Layout Module Level 1 |
| Grid | CSS Grid Layout Module Level 1 и 2 (subgrid) |
| Поддержка браузерами | Flexbox — с 2015, Grid — с 2017, subgrid — с 2023 |
| Стандартизация | W3C CSS Working Group |
| Связанные свойства | gap, align-items, justify-content, place-items |
Flexbox и Grid — два модуля раскладки (layout) в CSS, которые задают, как дочерние элементы контейнера располагаются и делят между собой свободное место. Flexbox работает в одном измерении — вдоль строки или колонки, Grid — в двух сразу, строками и колонками. Вместе они заменили приёмы прошлых лет: вёрстку таблицами, плавающие блоки (float) и inline-block с отрицательными отступами.[6]
История
До середины 2010-х в CSS не было механизма раскладки для интерфейсов: float придумывался для обтекания картинок текстом, а табличная вёрстка смешивала структуру HTML с оформлением. Черновик Flexbox появился в 2009 году, пережил три несовместимых синтаксиса и стабилизировался к 2012-му; к 2015 году его поддерживали все основные браузеры.[1] Grid вырос из предложения Microsoft (реализованного в IE10 с префиксом) и одновременно включился в Chrome, Firefox и Safari в марте 2017 года. Вторая версия Grid добавила subgrid — возможность вложенной сетке наследовать дорожки родителя; к 2023 году её поддерживают все движки.[5]
Flexbox
Контейнер становится flex-контейнером через display: flex. У него есть главная ось (по умолчанию горизонтальная, задаётся flex-direction) и поперечная ось.[3]
| Свойство | Где | Что делает |
|---|---|---|
flex-direction |
контейнер | направление главной оси: row, column |
flex-wrap |
контейнер | переносить ли элементы на новую строку |
justify-content |
контейнер | распределение вдоль главной оси |
align-items |
контейнер | выравнивание по поперечной оси |
gap |
контейнер | промежутки между элементами |
flex |
элемент | сокращение для flex-grow, flex-shrink, flex-basis |
order |
элемент | визуальный порядок |
Главная идея — гибкость размеров: flex: 1 говорит элементу забрать свою долю свободного места, flex: 0 0 200px — оставаться ровно 200 пикселей. Классические задачи, решаемые одной строкой:
/* центрирование по обеим осям */
.center { display: flex; justify-content: center; align-items: center; }
/* панель: логотип слева, меню справа */
.toolbar { display: flex; gap: 1rem; }
.toolbar .spacer { margin-left: auto; }
Grid
Grid-контейнер (display: grid) делится на дорожки (tracks) — строки и колонки, — а элементы размещаются в ячейках или областях.[4] Ключевые инструменты:
grid-template-columns/grid-template-rows— размеры дорожек; единицаfrозначает долю свободного места.repeat(),minmax(),auto-fill/auto-fit— адаптивные сетки без медиазапросов.grid-template-areas— именованные области, раскладка «рисуется» текстом.grid-column/grid-row— растянуть элемент на несколько дорожек.
/* карточки: столько колонок, сколько влезет, каждая не уже 16rem */
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
gap: 1rem;
}
/* раскладка страницы в духе вики */
.page {
display: grid;
grid-template-columns: 12rem 1fr;
grid-template-areas: "nav header" "nav main";
}
Что выбрать
Правило большого пальца: Flexbox — от содержимого, Grid — от раскладки. Если элементы выстраиваются в ряд и их размеры зависят от содержимого (кнопки, теги, меню) — это Flexbox. Если сначала задаётся сетка, а элементы раскладываются по ней (страница, галерея, форма с выровненными подписями) — Grid. На практике их сочетают: каркас страницы на Grid, компоненты внутри — на Flexbox. Свойство gap и свойства выравнивания (align-*, justify-*) общие для обоих модулей.
Доступность
Оба модуля меняют лишь визуальный порядок: order, flex-direction: row-reverse и размещение в Grid не трогают порядок в DOM, по которому идут клавиатурная навигация и экранные читалки. Расхождение визуального и логического порядка — частая ошибка; см. Веб-доступность (a11y).