Статьи

Создание макетов с помощью CSS Grid

Следующее введение в CSS Grid — это отрывок из книги Тиффани, CSS Master, 2nd Edition .

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

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

Контекст форматирования сетки

Добавление display: grid к элементу запускает контекст форматирования сетки для этого элемента и его дочерних элементов. В контексте форматирования сетки происходят три вещи:

  1. Элемент становится элементом уровня блока, который участвует в нормальном потоке.
  2. Его дочерние элементы, будь то элементы или текстовые узлы, создают блочные блоки уровня сетки, которые можно упорядочить в строки и столбцы. Непосредственные дочерние элементы контейнера сетки являются элементами сетки .
  3. В режиме горизонтальной записи каждый элемент в строке сетки будет иметь ту же высоту, что и его самый высокий элемент (в зависимости от содержимого), если не задано явное значение высоты. Когда документ использует режим вертикальной записи, он имеет ту же длину, что и его самый длинный элемент (в зависимости от содержимого).
Использование display: grid создает контейнер уровня блока и блоки блоков для его дочерних элементов. Использование display: grid создает контейнер уровня блока и блоки блоков для его дочерних элементов.

Использование display: inline-grid работает аналогично. Дочерние контейнеры сетки на уровне строк создают блоки уровня сетки, но сам контейнер участвует в контексте встроенного форматирования.

Использование display: inline-grid создает блок для встроенного уровня для контейнера, но блокирует блоки для его дочерних элементов. Использование display: inline-grid создает блок для встроенного уровня для контейнера, но блокирует блоки для его дочерних элементов.

Сами по себе display: grid и display: inline-grid не будут автоматически размещать эти поля в строки и столбцы. Нам также нужно сообщить браузеру, где и как размещать вещи.

Прежде чем создавать свою сетку, определите, хотите ли вы установить фиксированное количество столбцов и / или строк, хотите ли вы, чтобы браузер автоматически вычислял количество столбцов и строк, или же вы хотите использовать их сочетание. Знание того, какую сетку вы хотите создать, определяет подход, который вы выберете. Давайте посмотрим на несколько методов.

Определение схемы сетки

После определения контейнера сетки нам нужно сообщить браузеру, сколько строк и столбцов должна содержать наша сетка. Мы можем определить количество строк и столбцов, используя свойства grid-template-rows и grid-template-columns . Они применяются к сетке контейнера.

И grid-template-rows и grid-template-columns принимают то, что известно как список дорожек . Список дорожек представляет собой разделенную пробелами строку, которая определяет имена линий сетки и размеры каждой позиции в строке или столбце.

Каждое значение в списке дорожек создает новое пространство — дорожку — в строке или столбце. Вы можете использовать длины, гибкие единицы измерения длины (обсуждаемые далее в этой главе) или проценты. Вы также можете использовать значения размеров, такие как auto , min-content и max-conent .

 .grid { display: grid; grid-template-columns: 25rem 25rem 25rem; grid-template-rows: 10rem 10rem; } 

В приведенном выше коде мы определили сетку из трех столбцов, каждый шириной 25rem и двух строк, высотой 10rem . Давайте применим его к следующему HTML. Да, это все требуемая разметка:

 <div class="grid"> <div>Grid item A</div> <div>Grid item B</div> <div>Grid item C</div> <div>Grid item D</div> <div>Grid item E</div> </div> 

Наши элементы сетки организованы в столбцы и строки, показанные ниже.

Создание явной сетки с сеткой-шаблонами-столбцами и сеткой-шаблонами-строками Создание явной сетки с grid-template-columns и grid-template-rows

Здесь мы создали сетку из строк и столбцов одинакового размера, но это не является обязательным требованием для Grid. Давайте немного подправим наш CSS. Мы изменим значение grid-template-columns на 25rem 15rem 25rem :

 .grid { display: grid; grid-template-columns: 25rem 15rem 25rem; grid-template-rows: 10rem 10rem; } 

Теперь второй столбец в нашей сетке уже, чем первый и третий.

Столбцы и строки сетки не обязательно должны быть одинаковой ширины. Столбцы и строки сетки не должны быть одинаковой ширины.

Явная сетка против неявных сеток

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

Когда элементы сетки превышают количество явно определенных ячеек, остальные элементы располагаются в неявной сетке Когда элементы сетки превышают количество явно определенных ячеек, остальные элементы располагаются в неявной сетке

Теперь у нас есть три ряда. Заметьте, однако, что наш третий ряд только такой же высокий, как его содержимое и отступы. Это часть сетки, потому что эти элементы являются дочерними элементами контейнера сетки. Все же строка не определена явно grid-template-rows . Вместо этого мы имеем неявную сетку — явную сетку с дополнительными элементами сетки, которые превышают определенное количество явных ячеек сетки.

Элементы в неявной сетке auto выбираются по умолчанию. Элементы сетки будут расширяться, чтобы вместить их содержимое, или заполнять оставшееся вертикальное пространство в контейнере — в зависимости от того, что выше. Если, например, мы установим свойство height нашего контейнера в 50rem , наша неявная дорожка сетки будет расширена до 30rem .

Неявные строки сетки расширяются, чтобы заполнить доступную высоту контейнера Неявные строки сетки расширяются, чтобы заполнить доступную высоту контейнера

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

Высота неявных строк сетки будет равномерно распределена в зависимости от оставшегося пространства в контейнере сетки. Высота неявных строк сетки будет равномерно распределена в зависимости от оставшегося пространства в контейнере сетки.

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

Указание размера дорожки для неявной сетки

Однако можно установить вид явной высоты или ширины по умолчанию для неявных элементов сетки, используя свойства grid-auto-rows и grid-auto-columns . Давайте обновим наш CSS с помощью grid-auto-rows :

 .grid { display: grid; grid-template-columns: 25rem 15rem 25rem; grid-template-rows: 10rem 10rem; grid-auto-rows: 30rem; } 

Теперь элементы в нашем третьем ряду — и любые последующие ряды — будут 30rem в высоту.

Использование grid-auto-row для указания высоты неявных элементов сетки Использование grid-auto-rows для указания высоты неявных элементов сетки

Есть один недостаток использования свойств grid-auto-* : когда содержимое элемента сетки превышает его размеры, оно переполняет контейнер (показано ниже) и может визуально обрезаться элементами в других строках.

Содержимое контейнера сетки может переполнить контейнер при использовании единиц длины или процента Содержимое контейнера сетки может переполнить контейнер при использовании единиц длины или процента

Один из способов избежать этого — использовать minmax() . Давайте перепишем наш CSS, чтобы использовать minmax() :

 .grid { display: grid; grid-template-columns: 25rem 15rem 25rem; grid-template-rows: 10rem 10rem; grid-auto-rows: minmax(30rem, auto); } 

Как вы уже догадались из его названия, minmax() позволяет нам определить минимальный и максимальный размер дорожки. Требуется два аргумента, первый из которых — минимальный желаемый размер дорожки. Второй аргумент — это максимальный желаемый размер.

В этом случае наш ряд будет иметь 30rems не менее 30rems . Но так как мы установили наш максимальный размер на auto , наша дорожка будет расширяться, чтобы вместить содержимое этой ячейки. Аргументами для minmax() могут быть длины или проценты или одно из ключевых слов auto , min-content и max-content . Здесь minmax(30rem, max-content) достиг бы почти такого же эффекта. Гибкие единицы, обсуждаемые в следующем разделе, также действительны.

Длина и проценты могут быть использованы для определения размеров дорожки. Их использование может означать, что элементы сетки не заполняют всю ширину или высоту контейнера. Например, если наш контейнер-сетка имеет ширину 70rem , grid-template-columns: 25rem 15rem 25rem; заполнит только около 90% своего горизонтального пространства. С другой стороны, если наш контейнер с сеткой имеет ширину всего 50rem , общая ширина наших столбцов будет 50rem за границы контейнера.

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

Создание гибких сеток с помощью модулей Flex

Гибкая длина или гибкие единицы лучше всего понимать как дробные единицы и выражаются с использованием fr . Гибкие единицы указывают браузеру, какую долю или долю оставшегося пространства в контейнере сетки следует выделить каждому элементу сетки. Это отношение, а не истинное значение длины, как в px , em или cm .

Существует формула для расчета используемой ширины элемента при использовании гибких единиц: (flex × остаток пространства) & div; сумма всех гибких факторов . Например, 1000px ширина нашего контейнера сетки составляет 1000px , а значение grid-template-columns равно 3fr 2fr 1fr , то наши столбцы будут иметь 333.33px 500px , 333.33px и 133.33px . Ширина каждого столбца распределяется пропорционально от доступного пространства, как показано ниже.

Гибкие единицы длины поддерживают пропорции сетки, а не абсолютные длины Гибкие единицы длины поддерживают пропорции сетки, а не абсолютные длины

Поскольку эти единицы являются отношениями, а не абсолютными длинами, grid-template-columns: 2fr 2fr 2fr эквивалентен grid-template-columns: 1fr 1fr 1fr . И то и другое приведет к появлению столбцов одинаковой ширины для режимов горизонтальной записи и строк одинаковой высоты для режимов вертикальной записи.

Примечание: единицы измерения fr не являются истинными значениями длины. Это делает их несовместимыми с другими единицами длины, такими как px rem и ширина в процентах. Это также означает, что вы не можете использовать единицы измерения fr с функцией calc() . Например, calc(1fr - 1rem) является недопустимым значением длины.

Использование сокращенного свойства grid-template

Мы также можем указать количество строк и столбцов, используя свойство grid-template . Его синтаксис выглядит следующим образом:

 grid-template: [row track list] / 

Рассмотрим этот блок CSS:

 .grid { display: grid; grid-template-columns: 25rem 25rem 25rem; grid-template-rows: 10rem 10rem; } 

Мы можем объединить вторую и третью строки с помощью grid-template :

 .grid { display: grid; grid-template: 10rem 10rem / 25rem 25rem 25rem; } 

Однако, для ясности, вы все равно можете использовать свойства «от руки».

Повторяющиеся строки и столбцы

Во многих случаях вам понадобятся столбцы или строки сетки, которые повторяются автоматически; придумайте список предметов магазина или результаты поиска по рецепту. Для этого Grid предлагает синтаксис — функцию repeat() :

 .grid { display: grid; grid-template-columns: repeat(3, 1fr); } 

repeat() принимает два аргумента:

  1. количество повторений списка треков
  2. список треков, чтобы повторить

Аргументы должны быть разделены запятой. Первый аргумент может быть положительным целым числом или ключевыми словами с auto-fit или auto-fill . Приведенный выше CSS создает следующую сетку. Наш трек-лист 1fr повторяется три раза.

Повторяющаяся сетка с единицами измерения Повторяющаяся сетка с единицами измерения

Мы также можем использовать шаблон из двух столбцов, который повторяется дважды. Например, grid-template-columns: repeat(2, 1fr 3fr); производит сетку из четырех столбцов. Как показано на рисунке ниже, первый и третий столбцы составляют одну треть ширины второго и четвертого. В обоих случаях значение grid-template-rows равно auto .

Повторяющийся узор из двух колонок Повторяющийся узор из двух колонок

Повторяющиеся столбцы с auto-fit или auto-fill

Оба предыдущих примера сообщают браузеру: вот шаблон списка треков; пожалуйста, повторите это X раз . Вместо этого вы, возможно, захотите сообщить браузеру: пожалуйста, поместите как можно больше столбцов или строк в этом сеточном контейнере . Для этого мы можем использовать auto-fit или auto-fill в качестве первого аргумента для repeat() в сочетании с minmax() .

В чем разница между auto-fit auto-fill и auto-fill ? Это тонко, но важно.

  • auto-fill позволяет разместить как можно больше элементов сетки в пределах линии дорожки, добавляя анонимные дорожки сетки при необходимости.
  • auto-fit как можно больше элементов сетки в пределах линии дорожки, при необходимости расширяя или сворачивая размеры каждой дорожки .

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

 .grid { display: grid; width: 800px; } .autofill { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); } .autofit { grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); } 

И давайте применим этот CSS к HTML ниже:

 <div class="grid autofill"> <div>Grid item A</div> <div>Grid item B</div> <div>Grid item C</div> <div>Grid item D </div> <div>Grid item E</div> </div> <div class="grid autofit"> <div>Grid item A</div> <div>Grid item B</div> <div>Grid item C</div> <div>Grid item D </div> <div>Grid item E</div> </div> 

Единственное различие между этими двумя макетами сетки состоит в том, что один использует auto-fill а другой использует auto-fit auto-fill . Но сравните две сетки на изображении ниже.

Сравнение автозаполнения с автоподгонкой Сравнение auto-fill с auto-fit

В обеих сетках общая максимальная ширина элементов сетки меньше ширины контейнера сетки. Однако в верхней сетке — нашей сетке auto-fill это избыточное пространство заполняется анонимными элементами сетки.

Визуализация разницы между автоматическим заполнением и автоматическим соответствием с помощью инспектора сетки Firefox Визуализация разницы между auto-fill и auto-fit с помощью инспектора сетки Firefox

Сравните это с нижней сеткой, в которой каждый элемент сетки был растянут в соответствии с доступным пространством. Изображение выше иллюстрирует, как выглядят эти анонимные ячейки сетки с помощью инструментов разработчика Firefox.

Примечание. Если это по-прежнему не имеет смысла, прочитайте статью Сары Соуэйдана « Авторазмер столбцов в сетке CSS: auto-fill против автоподбора». Он содержит несколько примеров видео, которые иллюстрируют разницу немного лучше, чем статичные изображения.


Это отрывок из книги CSS Master, 2nd Edition . До этого момента мы рассмотрели простые сетки, которые представляют собой аккуратно выровненные строки и столбцы блоков. Далее в книге рассказывается о гораздо более сложных макетах, которые может обрабатывать Grid, включая размещение сетки на основе линий, именованные области сетки, как размещать элементы сетки и как работать с изображениями в сетках.

Вывод

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

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

Rachel Andrew’s Grid by Example была создана для аудитории веб-разработчиков. Сайт включает в себя учебники макета сетки и коллекцию общих шаблонов пользовательского интерфейса. Обязательно посетите раздел Ресурсы сайта тоже. Это рог изобилия ссылок, которые демонстрируют, что вы можете сделать с помощью CSS Grid.

Лаборатория экспериментальных макетов Джена Симмонса также полна примеров, иллюстрирующих возможности Grid. Если видео больше подходит вашему стилю, на канале Simmons ‘ Layout Land YouTube’ вы найдете видеообзоры по сетке и другие темы макета.

Если вам нужно больше справочников в стиле чит-листа, попробуйте « Полное руководство по сетке » от CSS-Tricks.