Главная » Статьи » Правильная верстка CSS Grid

Правильная верстка CSS Grid

Правильная верстка CSS Grid

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

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

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

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

Используйте имена, а не цифры

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

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

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

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

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

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

Добавление имен в сетку дает пару основных преимуществ. Удобочитаемость — ваш код легче понять. Ряд 3 теперь описывает все, что происходит внутри контейнера 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 в качестве гибкой единицы

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

fr отличается от % или vw, потому что, в то время как последние описывают части 100 единиц в целом, с помощью fr определяются пространства еще не занятые чем-либо еще. fr разделяет это пространство пропорционально. Здесь колонка content в два раза шире колонки sidebar.

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

Поскольку других единиц, кроме fr здесь нет, три fr будут занимать все пространство, 1fr = ~ 33% ширины сетки.

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

fr предлагает несколько вещей, которых другие гибкие блоки не имеют. Читаемость и более четкое намерение — Использование fr, в отличие от процентов, позволяет нам придерживаться целых чисел, которые задают размеры относительно друг друга, а не относительно целого. Это сохраняет предполагаемое поведение ясным. Например, ряд 3 легко перевести на человеческий язык: «Контент в два раза шире боковой панели».

fr также позволяет вам разделить пространство таким образом, который было бы сложно рассчитать (и прочитать) с использованием процентов.

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

Меньше математики. Самым большим преимуществом fr является то, что эта единица передает выполнение точной арифметики от разработчика движку верстки браузера. Например, вот CodePen, иллюстрирующий два способа создать один и тот же макет с помощью CSS Grid. Эти строки — суть демо:

.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 может игнорировать размер зазора и нам не потребуется новая математика, если мы обновим количество колонок. Это легко читать и это более стабильно.

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

Эта противоречивая рекомендация выходит за рамки спецификации CSS Grid и сводится к тому, как работает веб-дизайн и как разработчики взаимодействуют с дизайнерами. Макеты часто понимаются как элементы, выровненные по сетке.

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

В приведенном выше примере у нас есть сетка из 14 столбцов со следующими элементами, которые нужно разместить и распределить.

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

Боковая панель, которая начинается в колонке 2 и охватывает 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;
}

Но действительно ли это хороший план? Попытка воспроизведения дизайна 1: 1 имеет два недостатка. Во-первых, это мешает именовать колонки. Кроме того, из наших 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;
}

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

Мы можем продолжить эту парадигму по всему макету. Скажем, внутри элемента .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.

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

.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>

.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.

Заключение

Спасибо, что прошли со мной это путешествие по CSS Grid! Я пользуюсь ей последние пару месяцев, и мне она нравится, я надеюсь, что это поможет вам понять и использовать ее.

Возвращаясь к моим словам из вступления — CSS Grid прост в использовании, но сложен в освоении. Это более интуитивная парадигма, чем любая другая техника верстки CSS, но она полностью отличается от своих предшественников.

Все это говорит нам: принимайте Grid настолько постепенно, насколько вам необходимо. Не пытайтесь понять все это только прочитав спецификацию. Возьмите простые примеры, откройте веб-инспектор (особенно в Firefox!) и будьте снисходительны к себе. Оно того стоит.

Источник: https://vgpena.github.io/

Редакция: Команда webformyself.