CSS-гриды + CSS-колонки = ♥

Перевод статьи CSS Grid + CSS Multi-Columns = ♥ с сайта medium.com для CSS-live.ru, автор — Патрик Броссет

В этой короткой статье я рассматриваю связь между двумя раскладочными инструментами из CSS: CSS-гриды и CSS-колонки.

Эти два инструмента можно использовать вместе весьма интересными способами для построения отзывчивых веб-дизайнов.

Начнём с обзора, что каждый из их делает.

CSS-колонки

CSS уже давно умел размещать контент по колонкам, и у них очень хорошая поддержка во всех актуальных браузерах (правда, для них по-прежнему нужны префиксы). (прим. перев.: для актуальных версий уже и префикс не нужен)

Чаще всего CSS-колоноки нужны, чтобы разбивать длинные разделы текста на несколько колонок, чтобы строки не становились такими длинными, что их неудобно читать.

Прелесть CSS-колонок в том, что их можно определять с помощью одного лишь CSS и без дополнительной разметки. Контент перетекает из колонки в колонку, естественно и автоматически, в зависимости от доступной ширины.

Например, можно определить совсем простую многоколоночную раскладку с помощью CSS-свойства column-width: 150px; и браузер просто добавит в доступную область столько колонок, сколько их вмещается:

Длинный текст перетекает из колонки в колонку

CSS-гриды

CSS-гриды — новая потрясающая система CSS-раскладки, позволяющая разработчику очень легко размещать элементы по двумерной сетке.

Если вы хотя бы краем уха не слышали об этом за весь прошлый год, вы, должно быть, живете в глухом лесу. Огромное количество статей, документаций, видео и докладов было довольно сложно не заметить.

Зайдите на сайты Джен Симмонс, Рейчел Эндрю или песочницу Мозиллы по гридам, чтобы узнать о гридах всё.

Колонки + гриды = ♥

Давайте для начала создадим простую грид-раскладку, которая размещает друг за другом набор полей ввода с их подписями, в две колонки:

<style>
.grid { display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: 2em; grid-gap: .5em;
}
</style>
<div class="grid"> <label>label</label> <input type="text"> <label>label</label> <input type="text"> <label>label</label> <input type="text"> ...
</div>

В CSS выше создаются две колонки одинакового размера, которые будут автоматически заполняться элементами, как показано ниже:

Простой двухколоночный грид на CSS

А вот теперь интересный момент: на самом деле можно разместить грид в колоночной раскладке! И это просто круто!

В принципе, грид поддерживает разбивку на фрагменты, а значит он тоже будет перетекать по колонкам. Он будет разбит на фрагменты, где нужно, по фрагменту на колонку. Эти фрагменты — всего лишь части одного и того же грида.

Итак, давайте возьмём простой пример формы на основе грида, и посмотрим что будет, если положить её внутрь многоколоночной раскладки с column-width: 150px:

CSS-грид разбился на несколько фрагментов.

Посмотрите, как по мере доступной области грид разбивается по фрагментам, чтобы занять доступные колонки.

Вот так мог бы выглядеть весь код:

<style>
.columns { column-width: 200px; max-width: 800px; margin: 0 auto;
}
.grid { display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: 2em; grid-gap: .5em;
}
</style>
<div class="grid"> <label>label</label> <input type="text"> <label>label</label> <input type="text"> <label>label</label> <input type="text"> ...
</div>

В числе прочего, замечательно здесь то, что весь контент находится в одном гриде, даже когда грид разбивается по нескольким фрагментам. Поэтому, к примеру, размер грид-колонки будет всегда одинаковым во всех фрагментах.

Фрагментирование внутренних отступов и границ

Если по какой-то причине вам захочется добавить самому гриду границу и внутренний отступ, тогда произойдёт примерно следующее:

Обрезанные границы и отступы

И правда, элемент, к которому применен грид, разбивается на фрагменты по многоколоночному контейнеру, но верхняя сторона у него по-прежнему лишь одна, как и нижняя. Поэтому, к примеру, нижняя граница применяется только к нижней стороне грид-элемента.

Очевидно, выглядит не очень. К счастью, и это можно решить с помощью CSS — свойства box-decoration-break. Оно определяет, как фон, границы, внешние и внутренние отступы должны работать в случаях с фрагментацией (или в случаях, когда инлайн-элемент переносится на несколько строк текста).

С помощью box-decoration-break: clone; можно получить ожидаемое поведение:

Границы и отступы теперь клонированы во всех фрагментах

Вот и всё! Можете поиграть со сложными примерами здесь на codepen, он также включает несколько забавных маленьких CSS-счётчиков, благодаря которым я пронумеровал подписи одним лишь CSS.

Счастливого коддинга, и до встречи!

P.S. Это тоже может быть интересно: