CSS Grid Level 2: А вот и подсетка
Опубликовано: 2022-03-10Прошло больше года с тех пор, как CSS Grid Layout появился в большинстве наших браузеров, и рабочая группа CSS уже работает над уровнем 2 спецификации. В этой статье я собираюсь объяснить, что в настоящее время является частью рабочего и редакционного черновика этой спецификации. Обратите внимание, что все здесь может быть изменено, и в настоящее время ничего из этого не работает в браузерах. Воспринимайте это как беглый взгляд на процесс, я уверен, что буду писать больше практических статей, когда мы начнем видеть, как реализации обретают форму.
Уровни спецификации CSS
Функции CSS Grid, которые мы сейчас можем использовать в браузерах, относятся к Уровню 1 спецификации CSS Grid. Различные части CSS разбиты на модули; эта модульность произошла, когда CSS перешел от CSS 2.1, поэтому вы иногда слышите, как люди говорят о CSS3. На самом деле CSS3 не существует. Вместо этого был набор модулей, который включал в себя все, что уже было частью спецификации CSS2.1. Любой CSS, существовавший в CSS2.1, стал частью модуля уровня 3, поэтому у нас есть селекторы CSS уровня 3, поскольку селекторы существовали в CSS2.1.
Новые функции CSS, которые не были частью CSS2.1, такие как CSS Grid Layout, начинаются с уровня 1. Спецификация CSS Grid Level 1 — это, по сути, первая версия Grid. Как только уровень спецификации получает статус кандидата в рекомендации, основные новые функции не добавляются. Это означает, что браузеры и другие пользовательские агенты могут реализовать спецификацию, и она может стать рекомендацией W3C. Если должны быть разработаны новые функции, они будут реализованы на новом уровне спецификации. На данный момент мы работаем с CSS Grid Layout. Спецификация уровня 1 находится на уровне CR, а спецификация уровня 2 была создана для работы над новыми функциями. Я бы посоветовал просмотреть редакционный черновик, если вы хотите следить за обсуждением спецификаций, так как он будет содержать все последние изменения.
Что будет содержать CSS Grid уровня 2?
В конечном итоге спецификация уровня 2 будет содержать все, что уже есть в спецификации уровня 1, а также некоторые новые функции. Если вы взглянете на спецификацию на момент написания, там есть примечание, объясняющее, что весь уровень 1 должен быть скопирован, как только уровень 2 достигнет CR.
Затем мы можем ожидать появления некоторых новых функций, а уровень 2 спецификации сетки полностью посвящен разработке функции подсетки в CSS Grid. Эта функция была исключена из спецификации уровня 1, чтобы дать время для правильного понимания вариантов использования подсетки и дать больше времени для работы над ней, не задерживая остальную часть уровня 1. В оставшейся части этой статьи я взгляните на функцию подсетки, поскольку она в настоящее время подробно описана в черновике редактора. Мы находимся на очень ранней стадии разработки этой функции, однако сейчас самое подходящее время, чтобы следить за ней и фактически помочь сформировать то, как разрабатывается спецификация. Моя цель при написании этой статьи — объяснить некоторые из обсуждаемых вещей, чтобы вы могли понять и внести свой вклад в обсуждения.
Что такое подсетка?
При использовании CSS Grid Layout вы уже можете вкладывать сетки. В приведенном ниже примере у меня есть родительская сетка с шестью дорожками столбцов и дорожками с тремя строками. Я разместил элемент в этой сетке от строки столбца 2 до строки 6 и от строки строки 1 до строки 3. Затем я сделал этот элемент контейнером сетки и определил дорожки столбцов.
.grid { display: grid; grid-template-columns: 1fr 2fr 1fr 2fr 1fr 2fr; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: 2fr 1fr 2fr 1fr; }
Дорожки нашей вложенной сетки не имеют отношения к дорожкам родителя. Это означает, что если мы хотим иметь возможность выравнивать дорожки нашей вложенной сетки с линиями внешней сетки, мы должны проделать работу и использовать методы вычисления размеров дорожек, которые гарантируют, что все дорожки останутся одинаковыми. В приведенном выше примере дорожки будут выглядеть выровненными, пока элемент большего размера не будет добавлен в одну ячейку сетки (из-за чего он займет больше места).


Для столбцов часто можно обойти описанный выше сценарий, ограничивая гибкость сетки. Вы можете сделать свои столбцы единиц fr
minmax(0,1fr)
, чтобы они игнорировали размер элемента при распределении пространства, или вы можете вернуться к использованию процентов. Однако это лишает некоторых преимуществ использования сетки, и, когда дело доходит до выравнивания строк во вложенной сетке, эти методы не будут работать.
Допустим, нам нужен макет карты, в котором отдельные карты имеют заголовок, тело и нижний колонтитул. Мы также хотим, чтобы верхний и нижний колонтитулы выровнялись по карточкам.
.cards { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 20px; } .card { display: grid; grid-template-rows: auto 1fr auto; }

Это работает до тех пор, пока содержимое имеет одинаковую высоту в верхнем и нижнем колонтитулах. Если у нас есть дополнительный контент, то иллюзия разрушается, и верхние и нижние колонтитулы больше не выстраиваются в ряд.

Создание подсетки
Теперь мы можем взглянуть на то, как в настоящее время определяется функция подсетки и как она может решить проблемы, которые я показал выше.
Примечание . На момент написания ни один из приведенных ниже кодов не работал в браузерах. Целью здесь является объяснение синтаксиса и концепций. Окончательная спецификация также, вероятно, изменится из-за этих деталей. Для справки: я написал эту статью на основе редакционного черновика, доступного 23 июня 2018 года.
Чтобы создать вложенную сетку, у нас будет новое значение для grid-template-rows
и grid-template-columns
. Эти свойства обычно используются со списком дорожек, который определяет количество и размер дорожек строк и столбцов. Однако при создании подсетки вы не хотите указывать эти дорожки. Вместо этого вы используете значение subgrid
, чтобы сообщить сетке, что эта вложенная сетка должна использовать количество дорожек и размер дорожек, которые охватывает область сетки, которую она покрывает.
В приведенном ниже коде у меня есть родительская сетка с дорожками из 6 столбцов и дорожками из 3 строк. Вложенная сетка является элементом сетки в этой родительской сетке и простирается от строки столбца 2 до строки столбца 6 и от строки строки 1 до строки строки 4. Это точно так же, как наш первоначальный пример, однако теперь мы можем взглянуть на него, используя подсетка. Вложенная сетка имеет значение subgrid
как для grid-template-columns
так и для grid-template-rows
. Это означает, что вложенная сетка теперь имеет дорожки из 4 столбцов и дорожки из 2 строк, используя тот же размер, что и дорожки, определенные в родительском элементе.
.grid { display: grid; grid-template-columns: 1fr 2fr 1fr 2fr 1fr 2fr; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid; }

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

Одномерные подсетки
Вы можете иметь вложенную сетку в одном измерении и указать размер дорожки в другом. В следующем примере подсетка указана только для grid-template-columns
. В свойстве grid-template-rows
указан трек-лист. Таким образом, дорожки столбцов останутся такими же, как четыре дорожки, которые мы видели выше, но дорожки строк могут быть определены отдельно от дорожек родителя.
.grid { display: grid; grid-template-columns: 1fr 2fr 1fr 2fr 1fr 2fr; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: subgrid; grid-template-rows: 10em 5em 200px 200px; }
Это означает, что строки вложенной сетки будут вложены внутрь родительской сетки, как и при создании вложенной сетки сегодня. Поскольку наша вложенная сетка охватывает две строки родителя, одну или обе эти строки необходимо будет расширить, чтобы содержать содержимое подсетки, чтобы не вызывать переполнения.
Вы также можете иметь подсетку в одном измерении, а в другом измерении использовать неявные дорожки. В приведенном ниже примере я не указал ни одной дорожки строк и дал значение для grid-auto-rows
. Строки будут созданы в неявной сетке указанного размера, и, как и в предыдущем примере, родительскому элементу потребуется место для этих строк или расширение, чтобы содержать их.
.grid { display: grid; grid-template-columns: 1fr 2fr 1fr 2fr 1fr 2fr; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: subgrid; grid-auto-rows: minmax(200px, auto); }
Нумерация строк и подсетка
Если мы снова взглянем на наш первый пример, размер дорожек нашей подсетки определяется родителем в обоих измерениях. Однако номера строк во вложенной сетке действуют как обычно. Первая строка столбца в линейном направлении — это строка 1, а строка в дальнем конце линейного направления — это строка -1. Вы не ссылаетесь на строки подсетки с номером строки родителя.
.grid { display: grid; grid-template-columns: 1fr 2fr 1fr 2fr 1fr 2fr; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid; } .subitem { grid-column: 2 / 4; grid-row: 2; }

Промежутки и подсетки
Вложенная сетка наследует любой зазор между столбцами или строками, установленный в родительской сетке, однако это может быть переопределено зазорами между столбцами и строками, указанными во вложенной сетке. Если, например, в родительской сетке column-gap
был установлен на 20 пикселей, а в подсетке затем был установлен column-gap
в столбцах, равный 0, ячейки сетки подсетки увеличились бы на 10 пикселей с каждой стороны, чтобы уменьшить зазор до 0, с линия сетки, по существу, проходит по середине зазора.
Теперь мы можем увидеть, как подсетка поможет нам решить второй вариант использования из начала этой статьи, когда карточки с верхними и нижними колонтитулами выстраиваются в ряд по карточкам.
.grid { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-auto-rows: auto 1fr auto; grid-gap: 20px; } .card { grid-row: auto / span 3; /* use three rows of the parent grid */ display: grid; grid-template-rows: subgrid; grid-gap: 0; /* set the gap to 0 on the subgrid so our cards don't have gaps */ }

Имена линий и подсетка
Любые имена линий в вашей родительской сетке будут переданы во вложенную сетку. Следовательно, если бы мы назвали линии в нашей родительской сетке, мы могли бы расположить элемент в соответствии с именами этих линий.
.grid { display: grid; grid-template-columns: [a] 1fr [b] 2fr [c] 1fr [d] 2fr [e] 1fr [f] 2fr [g]; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: subgrid; grid-template-rows: 10em 5em 200px 200px; } .subitem { grid-column: c / e; }

Вы также можете добавить имена линий в свою вложенную сетку, линии сетки могут иметь несколько имен линий, поэтому эти имена будут добавлены к линиям. Чтобы указать имена строк, добавьте список этих имен после значения subgrid
grid-template-columns
и grid-template-rows
. Если мы возьмем наш приведенный выше пример, а также добавим имена к линиям подсетки, мы получим два имени строки для любой строки в подсетке.
.grid { display: grid; grid-template-columns: [a] 1fr [b] 2fr [c] 1fr [d] 2fr [e] 1fr [f] 2fr [g]; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: subgrid [sub-a] [sub-b] [sub-c] [sub-d] [sub-e]; grid-template-rows: 10em 5em 200px 200px; } .subitem { grid-column: c / e; }

Неявные дорожки и подсетка
Как только вы решили, что измерение вашей сетки является подсеткой, это лишает вас возможности иметь какие-либо дополнительные неявные дорожки в этом измерении. Если вы добавите больше элементов, которые могут поместиться, дополнительные элементы будут помещены в последнюю доступную дорожку подсетки так же, как элементы обрабатываются в слишком больших сетках. Для области сетки, созданной во вложенной сетке, которая охватывает больше дорожек, чем доступно, последняя строка будет установлена на последнюю строку вложенной сетки.
Однако, как объяснялось выше, одно измерение вашей вложенной сетки может вести себя точно так же, как обычная вложенная сетка, включая неявные дорожки.
Вовлечение в процесс
Работа рабочей группы CSS происходит публично, на GitHub, как и в любом другом проекте с открытым исходным кодом. Это несколько облегчает отслеживание того, что происходит в списке рассылки. Вы можете взглянуть на проблемы, поднятые на уровне 2 спецификации CSS Grid, выполнив поиск проблем, помеченных как css-grid-2, в репозитории GitHub рабочей группы CSS. Если вы можете поделиться мыслями или примером использования любой из этих проблем, это будет приветствоваться.
Есть и другие функции, которые люди запрашивали для CSS Grid Layout, и тот факт, что они не были включены в уровень 2, не означает, что они не рассматриваются. Вы можете видеть уровни, поскольку выпуск функции может быть в продукте, только потому, что какая-то функция не является частью текущего спринта, не означает, что это никогда не произойдет. Работа над новыми функциями веб-платформы, как правило, занимает немного больше времени, чем средний выпуск продукта, но это аналогичный процесс.
Сколько времени это все занимает?
Разработка спецификации и реализация браузера — циклический итеративный процесс. Дело не в том, что спецификацию нужно «закончить», прежде чем мы увидим некоторые реализации браузера. Первоначальные реализации, скорее всего, будут скрыты флагами функций — как и исходная спецификация сетки. Следите за их появлением, так как когда есть код, с которым можно играть, становится намного проще думать об этих функциях!
Я надеюсь, что этот тур о том, что может произойти в ближайшее время, был интересным. Я взволнован тем, что функция подсетки находится в стадии разработки, так как я всегда считал ее жизненно важной для полной системы компоновки сетки для Интернета.