Правильно используем CSS Grid

6039

Правильно используем CSS Grid

В этой статье вы узнаете о том, как использовать нэйминг в CSS Grid. Как применять fr и почему не надо практиковать систему сеток с CSS Grid, звучит странно, да? Давайте посмотрим почему.

Правильно используем CSS Grid
Правильно используем CSS Grid

CSS Grid это надежный, гибкий и освежающий сдвиг парадигмы от других подходов вёрстки на CSS. И пока у гридов есть свои фишки, они же и усложняют процесс понимания этих самых гридов.

Изучение CSS Grid требует рабочего понимания многих новых свойств, которые не просто описывают один аспект отрисовки или поведения на странице, а влияют на всю систему разметки. Эта система включает в себя около 18 свойств, которые используют парадигмы и синтаксис, редко использующиеся (или вообще нет) в каких либо других CSS спеках.

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

В этой статье, я хочу помочь вам в преодолении этого порога вхождения, показав самые эффективные способы применения гридов. Я не рассказываю тут про всю спеку гридов — для этого вы можете посмотреть этот пост с CSS Tricks или тут Вёрстка на Grid в CSS. Полное руководство и справочник. То, о чем я рассказываю тут, по-моему мнению полезные аспекты работы с этой системой верстки.

Используйте имена, а не числа

Колонки и строки в гридах, в своей основе, определяются числами. Для примера, этот CSS делает грид с двумя колонками и размещает основной контент страницы во второй колонке:

.container {
    display: grid;
    grid-template-columns: 1fr 2fr;
}
.content {
    grid-column: 2;
}

Это работает, но тут упускается очень клевая фича в CSS Grid: вы можете давать вашим строкам и колонкам свои имена. Вам нужно пользоваться этим преимуществом, где это только возможно. Вот тот-же CSS, только с использованием имён:

.container {
    display: grid;
    grid-template-columns: [sidebar] 1fr [content] 2fr;
}
.content {
    grid-column: content;
}

Даже в таких простых случаях, как этот, именование грид-областей будет вам удобно.

Почитайте больше про grid-area в этой статье Поразительный CSS Grid Area

Преимущества

Раздача имен в гриде даёт несколько больших преимуществ.

Читабельность — тут всё понятно, ваш код проще понять.

Третья строка кода теперь описывает всё, что находится внутри Grid-контейнера. Вы не просто перечисляете колонки; вы указываете для чего предназначена каждая колонка.

На 7-й строке всё так-же становится довольно описательным. До этого, мы только знали то, что .content находился во второй колонке, что не о многом то и говорило без дополнительного контекста — колонка 2 из 3 или 2 из 200? Указание имени колонки указывает на то, что элемент был учтён внутри системы побольше. Так же, нэйминг упрощает поиск исходного объявления колонки, если нам это будет нужно.

Задел на будущее — добавление имён делает ваш CSS более гибким. В частности, вы можете перебирать элемент в .container без нужды в редактировании .content.

Хотите поменять визуальный порядок между контентом и сайдбраром? Легко!

.container {
    display: grid;
    grid-template-columns: [content] 2fr [sidebar] 1fr;
}
.content {
    grid-column: content;

Хотите добавить ещё одну колонку? Без проблем.

.container {
    display: grid;
    grid-template-columns: [related-posts] 1fr [sidebar] 1fr [content] 2fr;
}
.content {
    grid-column: content;
}

Без именования колонок, вам бы пришлось обновлять номер колонки в 7-ой строке, чтобы соответствовать изменениям, сделанным в 3-ей строке. Проименованные колонки дают .content согласованное поведение, которое не зависит от порядка столбцов и их количества.

Используйте fr, как единицу гибкости

Про fr довольно подробно написано тут — Что такое единица гибкости fr в CSS, доступным и простым языком

В CSS Grid представлена единица гибкости fr, которая указывает области занять определенную часть от всего доступного пространства. Пока fr может казаться заметкой в спеке на CSS Grid, но на самом деле она незаменима.

Единица fr отличается от % и vw, так как эти единицы указываются по частям от 100, а fr’ы указываются по месту, которое ещё не используется. В общем, они разделяют свободное место между собой.

Вот тут, колонка content в два раза шире, чем колонка sidebar.

.container {
    display: grid;
    grid-template-columns: [sidebar] 1fr [content] 2fr;
}
.content {
    grid-column: content;
}

Так как тут нет единиц не-fr и в сумме тут три fr’а, то 1fr = ~33% от ширины грида.

Преимущества

У fr есть несколько особенностей, которых недостает другим “гибким” единицам измерения.

Читабельность и ясное описание — использование fr, в отличие от применения процентов, даёт нам возможность придерживаться чисел, которые формируют размер относительно друг друга, а не относительно всей страницы или контейнера. Это позволяет поведению быть ясным и понятным. Для примера, третья строка прямо говорит о том, что контент в два раза шире, чем сайдбар.

fr’ы так же позволяют вам разделить место в случаях, когда его сложно бы было высчитать с использованием процентов.

.container {
    display: grid;
    grid-template-columns: [sidebar] 3fr [content] 4fr;
}

Меньше математики — самое большое преимущество fr в том, что она берёт на себя арифметические вычисления разработчика и переедет их на совесть движка браузера. Для примера, вот CodePen, показывающий два способа сделать один и тот же шаблон на гридах.

Вот в чем суть этих демок:

.percents, .frs {
    display: grid;
    grid-column-gap: 20px;
}
.percents {
    grid-template-columns: repeat(3, calc((100% - 40px)/3))
}
.frs {
    grid-template-columns: repeat(3, 1fr);
}

Код на 7 строке нелегко написать, тяжело читать и он нестабилен. Любое изменение в grid-column-gap или в количестве колонок, просто сломает шаблон, пока мы вручную не обновим ширину колонок для нужного нам соответствия.

Строка 11 может игнорировать размер gap’а и не будет требовать каких-либо новых математических вычислений, если мы обновим количество колонок. Это просто легко читать и это хороший задел под будущие правки, с которыми не будет проблем.

Не используйте систему сеток

Эта противоречивая рекомендация выходит за рамки спеки о гридах и углубляется в то, как работает веб дизайн и то, как разработчики взаимодействуют с дизайнерами и плодами их работы.

Разметка зачастую воспринимается как элементы выстроенные вдоль системы сетки.

Не используйте систему сеток
Не используйте систему сеток

Обычно разработчики стремятся к точному соответствию с дизайном. Если дизайн основан на 14-ти колоночной сетке, то разработчик сделает схожую 14-ти колоночную сетку в коде и напишет вспомогательные классы, чтобы элементы охватывали 1, 2, 3, 6 и т.п. колонки. Большинство фронт-энд фреймворков, таких, как Bootstrap работают схожим способом.

В примере выше, у нас есть 14-ти колоночная сетка, со следующими элементами, которым нам надо выдать размер и разместить:

Header, который начинается с колонки 2 и охватывает 12 колонок.

Sidebar, который начинается со второй колонки и охватывает 4.

Основной контент, который начинается на 6-й колонке и охватывает 8.

В CSS Grid, очень легко настроить систему сеток так, чтобы она соответствовала дизайну.

.main {
    display: grid;
    grid-column-gap: 2rem;
    grid-row-gap: 1rem;
    grid-template-rows: [header] 100px [body] auto;
    grid-template-columns: repeat(14, 1fr);
}
.header {
    grid-row: header;
    grid-column: 2 / span 12;
}
.sidebar {
    grid-row: body;
    grid-column: 2 / span 4;
}
.content {
    grid-row: body;
    grid-column: 6 / span 8;
}

Но действительно ли это хороший план? Наша попытка создания точной копии имеет два недостатка.

Во-первых, это рушит все наши планы по неймингу колонок. Более того, из наших 14 колонок, мы “используем” только колонки 2, 5, 6 и 13. Технически это работает, но подразумевает плохой показатель отношения сигнал/шум (Отношение чистого аудиосигнала к шуму, создаваемому самим устройством. Это образное сравнения автора).

Обе эти проблемы можно решить, если мы немного отступимся от изначального дизайна:

.main {
    display: grid;
    grid-column-gap: 2rem;
    grid-row-gap: 1rem;
    grid-template-rows: [header] 100px [body] auto;
    grid-template-columns: [left-gutter] 1fr [sidebar] 4fr [content] 8fr [right-gutter] 1fr;
}
.header {
    grid-row: header;
    grid-column: sidebar / right-gutter;
}
.sidebar {
    grid-row: body;
    grid-column: sidebar;
}
.content {
    grid-row: body;
    grid-column: content;
}

Теперь вместо 14 колонок, у нас есть только 4, но они всё равно делят пространство в шаблоне на 14 частей. У нас такой же визуальный эффект, как и в первой итерации, но наш код не такой шумный и напрямую показывает что он, делает.

Мы можем продолжить использование этой парадигмы в нашем шаблоне. Скажем, к примеру, что внутри элемента .content нам нужно место для дополнительной информации (био автора, аннотация и тп), рядом с основной статьёй.

Если бы мы придерживались 14 колоночной сетки, то нам бы пришлось сделать как-то вот так:

.content {
    grid-row: body;
    grid-column: 6 / span 8;
}
.article {
    grid-column: 7 / span 4;
}
.info {
    grid-column: 11 / span 12;
}

Что будет довольно мутно, так как в CSS Grid отсутствует концепция наследования. .info ничего не знает о построении гридов в .main, то есть о своём прародителе.

Если мы избавимся от 14-ти колоночной сетки, то мы сможем заметить, что .article и .info не нужно вообще брать в расчёт гриды, которые стоят на порядок выше — они сами по себе являются частью нового грида внутри .content.

.content {
    grid-row: body;
    grid-column: content;
    display: grid;
    grid-template-columns: [left-gutter] 1fr [article] 4fr [info] 2fr [right-gutter] 1fr;
    grid-column-gap: 2rem;
}
.article {
    grid-column: article;
}
.info {
    grid-column: info;
}

Таким образом .content выглядит простым и соблюдает внутреннюю последовательность, а также идеально подстраивается под внешнюю расстановку внешних колонок в .main.

Преимущества

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

Не так важно, что .article начинается на 7-й колонке, а .info на 11-ой. Важно то, что .article в два раза шире, чем .info. Пропорциональное отношение к элементам и мысли о том, как они взаимодействуют друг с другом, помогают нам рассматривать шаблоны, как динамические системы.

Заметки на полях: вложенная разметка

Возможно, что вы уже подметили в примерах кода выше, то что мы использовали left-gutter и right-gutter колонки. Под таким CSS подразумевается самое ровное использование HTML, которое только возможно.

HTML:

<div class="main">
    <div class="header"></div>
    <div class="sidebar"></div>
    <div class="content"></div>
</div>

CSS:

.main {
    display: grid;
    grid-template-columns: [left-gutter] 1fr [sidebar] 4fr [content] 8fr [right-gutter] 1fr;
}

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

<div class="main">
    <div class="wrapper">
    <div class="header"></div>
    <div class="sidebar"></div>
    <div class="content"></div>
    </div>
</div>

С таким CSS:

.main {
    display: grid;
    grid-template-columns: [left-gutter] 1fr [wrapper] 12fr [right-gutter] 1fr;
}
.wrapper {
    grid-column: wrapper;
    display: grid;
    grid-template-columns: [sidebar] 1fr [content] 2fr;
}

По сути, второй подход кажется лучше, так как вычисления там проще — вы тут же забываете о числах, которые в сумме дают 14 и просто концентрируетесь на соотношении 1:2. Это уже в духе CSS Grid.

Но, а вот то, что совсем не в духе CSS Grid, так это добавление div’а .wrapper. Разметка на гридах усердно старается, чтобы помочь нам разделить представление от контента, то есть, нам не нужно добавлять дополнительные элементы, чтобы работала стилизация или она “вела себя нормально”. Поэтому, по крайней мере сейчас, я советую вам не добавлять новые элементы и/или изменять разметку только для того, чтобы у вас была более чистая(и сомнительно понятная) стилизация на CSS Grid.

Источник

Перевод статьи Using CSS Grid the right way