CSS Grid на практике: fr, растягивание ячеек и правила, которые стоит знать
Как на самом деле работают дорожки сетки, единица fr, отступы и spans, и в каких случаях grid выигрывает у flexbox, а в каких нет.
По-настоящему grid у меня в голове сложился в тот момент, когда я понял: 1fr — это не «одна треть». Это «одна доля от того, что осталось». Звучит одинаково, пока не появляется gap, и тогда одна из формулировок оказывается неверной.
Проверьте сами. Три колонки по 33.33% с отступом 20px вылезают за контейнер: проценты считаются от всей ширины и ничего не знают про 40px отступов, которые вы добавили. А repeat(3, 1fr) с тем же отступом встаёт ровно, потому что fr делит место, оставшееся после вычета фиксированных дорожек и всех gap. Все костыли эпохи float для колонок с промежутками существовали именно потому, что раньше такое вычитание было невозможно.
Grid появился в Chrome и Firefox с разницей в неделю в марте 2017 года — редкий случай синхронного релиза. Использовать его безопасно уже давно.
Как задавать размер дорожек
В повседневной работе вариантов четыре, и они отвечают на разные вопросы:
fr— поделить остаток. Для тех частей, которые должны тянуться.px— фиксированная дорожка. Сайдбар, колонка с иконками, всё, что не должно ездить.%— доля контейнера. Редко то, что нужно, если в раскладке есть отступы.auto— размер по содержимому. Удобно для колонки с подписями: ширина по самой длинной и ни пикселем больше.
Раскладка 240px 1fr — классический каркас приложения: фиксированный сайдбар, контент забирает остальное. Смешивать единицы — нормально, это не признак плохого кода.
В генераторе CSS Grid размер каждой дорожки задаётся отдельно, и результат видно сразу. Если все дорожки оказались одинаковыми, код сворачивается в repeat(n, размер) — короткую форму, которую обычно и пишут руками.
Растягивание ячеек и место, где все спотыкаются
grid-column: span 2 делает элемент шириной в две дорожки там, куда его поставит алгоритм автоматического размещения. grid-column: 2 / span 2 привязывает его ко второй линии и уже оттуда растягивает на две.
Путаница в том, что эти числа — номера линий, а не колонок. В сетке из трёх колонок четыре вертикальные линии: первая у левого края, четвёртая у правого. Поэтому grid-column: 1 / 4 растягивает элемент на всю ширину. Ошибка на единицу здесь — почти обряд посвящения.
Нажмите на любую ячейку в превью, и можно задать начальную линию, ширину в дорожках или и то и другое, по колонкам и по рядам. Каждый элемент, который отличается от значений по умолчанию, получает своё небольшое правило в коде, а те, которых вы не трогали, не дают ни строчки.
Значение по умолчанию, которое всех удивляет
justify-items и align-items по умолчанию равны stretch. Элементы заполняют ячейку целиком, поэтому цвет фона у дочернего элемента закрашивает всю ячейку, а не только область текста. Иногда на поиск несуществующего padding уходит минут двадцать.
Поставьте start, center или end — и элемент сожмётся до размера содержимого в этом направлении. Обычно этого достаточно.
Grid или flexbox
Grid управляет обеими осями, flexbox — одной. Дашборд, каркас страницы, галерея, где всё должно выравниваться и по рядам, и по колонкам, — это grid. Меню, группа кнопок, переносящийся ряд тегов — flexbox. На реальных страницах используют оба, а спор о том, что «лучше», примерно как спор молотка с отвёрткой.
Одну связку стоит утащить к себе: repeat(auto-fit, minmax(200px, 1fr)) даёт адаптивную сетку карточек вообще без медиазапросов. Визуальный конструктор такого пока не собирает, но после разбора с fr выше эта строчка читается сама собой.
Соберите раскладку в генераторе CSS Grid, скопируйте CSS и перестаньте угадывать. Всё работает в браузере, никуда ничего не отправляется.