CSS Grid Layout. Быстрый старт
Вступление
Всем привет. Февраль-Март 2017 года запомнились для многих, кто работает с HTML и CSS тем, что большинство браузеров выпустили обновления, среди которых были и обновления для CSS. Теперь можно использовать спецификацию CSS Grid Layout без флагов в следующих браузерах: Firefox 52, Chrome 57, Opera 44, Safari 10.1. Какой из браузеров остался позади, думаю, вы догадываетесь. Точнее он поддерживает старую версию спецификации. Но разработчики этого браузера делают все возможное, чтобы внедрить новую спецификацию. Внедрение поддержки новой CSS Grid Layout спецификации — это самое значимое событие за прошедшие пять лет. Эта спецификация поменяет полностью подход к разработке пользовательских интерфейсов. И это круто.
Я использую Flexible Box Layout
Многие задаются вопросом: «Стоп, я использую flexbox, зачем мне еще какие-то grid«ы?». Вопрос более чем уместен. CSS Grid не заменит Flexbox и наоборот. Первое отличие — это то, что Flexbox работает только в одном измерении. Из этого следует, что мы можем размещать flex элементы только вдоль главной оси или вдоль поперечной оси. Мы не можем разместить flex элементы сразу на нескольких осях. CSS Grid в свою очередь нам позволяет работать с разметкой в двухмерном пространстве и выравнивать содержимое в обоих измерениях. Мне нравится как объясняет эту разницу Tab Atkins.
Одна из самых больших проблем при разработке пользовательских интерфейсов — это то, что при изменении дизайна, функционала или поведения любого блока приходится менять его разметку (в большинстве случаев). CSS Grid позволяет менять расположение grid элементов не меняя сам HTML. Ниже пример простой разметки на Flexbox и CSS Grid.
Основные термины
Прежде чем приступать к работе с CSS Grid, нужно разобраться с основными терминами. На основе этих терминов построена вся спецификация.
Grid container — это набор пересекающихся горизонтальных и вертикальных grid линий, которые делят пространство grid контейнера на grid области, в которые могут быть помещены grid элементы. Внутри grid контейнера есть два набора grid линий: один определяет ось столбцов, другой определяет ось строк.
Grid lines — это горизонтальные и вертикальные разделители grid контейнера. Эти линии находятся по обе стороны от столбца или строки. Автор может задать для данного элемента имя или числовой индекс, которые может использовать дальше в стилях. Нумерация начинается с единицы. Важный нюанс, данный элемент восприимчив к режиму написания, который используется на вашем ресурсе. Например, вы используете Арабский язык или любой другой язык у которого режим написания справа налево, то нумерация линий будет начинаться с правой стороны.
Grid track — это пространство между двумя смежными grid линиями, вертикальными или горизонтальными.
Grid cell -это наименьшая неделимая единица grid контейнера на которую можно ссылаться при позиционировании grid элементов. Образуется на пересечении grid строки и grid колонки.
Grid area — это пространство внутри grid контейнера, в которое может быть помещен один или больше grid элементов. Этот элемент может состоять из одной или более grid ячеек.
Каждый элемент тесно связан друг с другом и отвечает за определенную часть grid контейнера.
Первый CSS Grid макет
Мы разобрались с основными терминами. Пришло время сделать наш первый grid макет. Ничего сложного, простенький макет три строки на три колонки, чтобы разобраться с основами. Ниже вы можете увидеть пример.
В первом варианте из примера мы создаем три колонки размером
150px 1fr 150px
и три строки размером 50px auto 50px
соответственно. Обратите внимание на такие значения: 1fr
, auto
. Давайте разберемся, что это за значения.1fr
— это специальная единица измерения введенная в данной спецификации. Она не измеряется в каких-то конкретных единицах измерения (px
, em
, rem
, др.) Из этого следует, что мы не можем использовать ее вместе с функцией calc()
. Эта единица измерения не может быть меньше единицы, а также не может принимать отрицательные значения. Она рассчитывается после того, как все остальные значения, отличные от fr
, были рассчитаны.
auto
— ведет себя довольно интересно и использует для расчета размеров хитрый алгоритм. В некоторых ситуациях может показаться, что эта единица измерения работает точно также как и fr
. Но это не так. Главное отличие, auto
будет рассчитан до того, как будет рассчитан fr
. Об этом нужно помнить. Вы можете увидеть данное поведение из второго и третьего вариантов примера, который приведен выше.
Для разметки колонок и строк используются следующие правила:
grid-template-columns: 150px 1fr auto;
grid-template-rows: 50px auto 50px;
Сокращенная форма записи выглядит так:
grid-template: 50px auto 50px / 150px 1fr auto;
Типичный шаблон на grid«ах
Давайте сделаем простенький шаблон с которым мы все знакомы. Ничего сложного, шаблон будет состоять из следующих тэгов:
header
, nav
, aside
, article
, footer
. Подавляющее большинство интернет ресурсов использует данный шаблон. Только знаете, даже в таком простом шаблоне наблюдается следующая проблема: «Я дизайнер, я так хочу. Я разработчик, я так не могу». С появлением CSS Grid Layout подобная проблема должна стремиться к нулю.В данном примере мы знакомимся еще с несколькими свойствами CSS Grid Layout. Первое
grid-template-areas
. Оно используется для создания именованных областей grid контейнера, которые не связаны с каким-либо конкретным grid элементом. Синтаксис очень удобен, мы сразу видим какой шаблон получится на выходе. Второе свойство grid-area
. Оно используется для дочернего элемента grid контейнера. Указывает в какую именованную область поместить grid элемент.Давайте рассмотрим первый вариант grid-template-areas
:
grid-template-areas: "header header"
"nav main"
"footer ."
Один или больше идущих подряд символов
.
(точка) имеют особое значение. Если этот символ используется, то браузер его отрендерит как нулевой токен, что в свою очередь означает следующее: на его месте не будет создана именованная область grid контейнера и в нее нельзя поместить grid элемент.Если мы не указали для какого-то дочернего grid элемента свойство grid-area
, браузер автоматически распределит такие элементы. Такое поведение можно увидеть из последнего варианта, приведенного примера выше.
Полезные ссылки
- CSS Grid Layout Module Level 1
- How to create a simple layout with CSS Grid Layouts
- Grid by Example от Rachel Andrew
- Подборка ресурсов для изучения CSS Grid Layout от Jen Simmons
- Ресурс для изучения СSS Grid Layout от Mozilla
- Jen Simmons про CSS Grid CSS Grid Layout
- Моя подборка ресурсов по CSS Grid Layout
Вместо заключения
В данной статье мы рассмотрели всего лишь верхушку CSS Grid Layout айсберга. Я начал обращать внимание на CSS Grid Layout еще когда все браузеры его поддерживали за флагами. Данный текст не способен передать мои впечатления от работы с этой спецификацией. Иногда сложно поверить своим глазам какие штуки удается сделать при помощи CSS Grid. Это разрыв всех шаблонов. И мне это нравится.
Я вам советую обратить внимание на данную спецификацию и потратить немного своего времени на ее изучение. Поверьте, в будущем вам это точно пригодится и не важно, пишите вы на React, Angular, Vue (вставьте свое). Grid«ы пришли надолго.
Напоследок добавлю пример с произвольным появлением grid элемента в разных именованных областях.
На этом все. Спасибо за внимание. Кто дочитал до конца, отдельное спасибо.
Комментарии (13)
7 апреля 2017 в 13:26
0↑
↓
Конечно интересно! Про полифилы ещё бы пару слов.
7 апреля 2017 в 13:48
+1↑
↓
Добрый день.
Спасибо за отзыв. Хорошо, сделаем. Добавлю пункт «Полифилы, Progressive Enhanced для CSS Grid Layout» в следующую статью.
7 апреля 2017 в 13:33
0↑
↓
Наконец-то в браузере появятся нормальные лейауты! FlexBox вместе с GridLayout покрывают практически всю необходимость разметки в приложениях.
А вообще, как-то странно: именно производители «того самого браузера» изначально предложили и пилили спецификацию GridLayout, теперь же хуже всех ее поддерживают.7 апреля 2017 в 14:01
0↑
↓
Теперь можно использовать спецификацию CSS Grid Layout без флагов в следующих браузерах: Firefox 52, Chrome 57, Opera 44, Safari 10.1. Какой из браузеров остался позади, думаю, вы догадываетесь. Точнее он поддерживает старую версию спецификации.
Вот если бы ещё все остальные браузеры умерли, а оставшиеся единомоментно проапгрейдились до вышеуказанных версий, было бы совсем отлично. А так всё равно придётся писать кучу флагов для совместимости.7 апреля 2017 в 14:09
0↑
↓
Добрый день.
А так всё равно придётся писать кучу флагов для совместимости.
Да, есть такое. Но можно завтавить машины страдать. И там получается не такая уж и большая куча)
7 апреля 2017 в 14:09
0↑
↓
вещь отличная grid, но немного рано еще их юзать по сравнению с flex
http://caniuse.com/#search=flex — поддерживают все современные браузеры
http://caniuse.com/#search=grid — некоторые версии не поддерживают
я думаю еще год и можно будет спокойно юзать grid для любого проекта… имхо7 апреля 2017 в 15:19
0↑
↓
Насчет последней строчки — сомнительно как-то.
Для узконишевых проектов (с технически продвинутой аудиторей) гриды можно будет применять уже в этом году.
А вот для широких масс, думаю, придется ждать еще минимум года 2, если не больше. Хвост эксплореров, опер мини и тому подобного будет волочиться ещё долго.7 апреля 2017 в 15:54
0↑
↓
Добрый день.
Да, полностью согласен. Я знаю много проектов, у которых целевой браузер — это Chrome. Вот где свобода для творчества.
7 апреля 2017 в 14:52
0↑
↓
Очень хочется, чтобы grid layout обогнал flexbox по скорости внедрения в браузеры.
Недавно MS принялась за запиливание гридов в текущей спецификации, которое прилетит с апдейтом во все их браузеры, включая 10-ку, что само по себе неплохо.
Когда начал первые эксперименты с сетками, получил очень много флешбеков :)Заголовок спойлера7 апреля 2017 в 16:28
0↑
↓
1fr, не может быть меньше единицы, а как тогда сделать header и footer, так чтобы их высота регулировалась бы высотой содержимого? Вот так почему то работает: grid-template-rows: 0fr auto 0fr;7 апреля 2017 в 16:53
+1↑
↓
Добрый день, Руслан.
Спасибо за интересный вопрос. Отвечу сначала как сделать так, чтобы высота header’a и footer 'a зависела от контента. Довольно просто, задайте значение
auto
или можно использовать функциюminmax()
со следующими значениямиminmax(auto, 10vh)
. что в свою очередь будет означать: максимам по высоте будет10vh
минимумauto
(по контенту).Вот так почему то работает: grid-template-rows: 0fr auto 0fr;
Конечно работает) Браузер умный и пытается посчитать значение. Тут можно почитать про алгоритм. Если в кратце, то браузер пытается высчитать гипотетическое значение 0_О. Не делайте так) Вы заставляете страдать браузер.
7 апреля 2017 в 16:55
0↑
↓
Пробовал auto X auto, но вместо X не знаю что подставить, 100% не работает)7 апреля 2017 в 16:59
0↑
↓
Ну вы явно что-то не так делаете. Покажите на примере. И опишите подробно как вы хотите, чтобы себя вели строки, колонки.