Копание в свойстве отображения: сетки полностью вниз

Опубликовано: 2022-03-10
Краткое резюме ↬ Продолжая серию статей о свойстве display в CSS, на этот раз Рэйчел Эндрю рассматривает, что происходит, когда вы используете сетку в качестве значения отображения, и добавляет информацию о том, как подсетка изменяет это поведение.

Сегодня мы рассмотрим, что происходит, когда мы используем display: grid , и как мы можем использовать новое значение подсетки grid-template-columns и grid-template-rows , чтобы разрешить сетки на всем протяжении нашей разметки. , которые относятся друг к другу.

Эта статья является частью серии, посвященной различным аспектам свойства display CSS, и является продолжением первых двух статей:

  1. Два значения display
  2. Генерация коробки
  3. Сетки полностью вниз

Что происходит, когда мы создаем грид-контейнер?

CSS Grid Layout включается с помощью display: grid . Если вы читали первую статью в этой серии, вы знаете, что на самом деле это свойство с одним значением означает display: block grid . Мы получаем блок уровня блока, который определяется как контейнер сетки , с прямыми дочерними элементами, которые являются элементами сетки и участвуют в компоновке сетки.

Если вы посмотрите на спецификацию дисплея, вы увидите это в таблице, которая определяет все различные значения для display . Слова грид-контейнер связаны с определением грид-контейнера в спецификации грид. Поэтому, чтобы узнать, что это на самом деле означает, нам нужно заглянуть туда. Когда мы это делаем, мы получаем полезное разъяснение поведения грид-контейнера.

Еще после прыжка! Продолжить чтение ниже ↓

Говорят, что контейнер сетки устанавливает контекст форматирования сетки, аналогичный контексту форматирования блока (BFC). Я написал подробное руководство по контексту форматирования блоков. В этой статье вы обнаружите две вещи о BFC, которые одинаковы для контекста форматирования сетки. Поплавки не вторгаются в контейнер сетки, а поля контейнера не схлопываются с полями содержимого.

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

Если какой-либо элемент в макете плавает или очищается, свойства float и clear не действуют, когда элемент становится элементом сетки. Свойство vertical-align не действует, а ::first-letter и ::first-line использовать нельзя.

Тот факт, что элемент не может быть одновременно плавающим и элементом сетки , полезен с точки зрения создания запасных вариантов. При создании резервной копии для браузеров, не поддерживающих сетку с использованием поплавков (когда сетка поддерживается), ничего особенного делать не нужно: поплавок перезаписывается.

Я описал этот подход в своей статье о поддержке браузеров без сетки. Бывают ситуации, когда поведение оказывается проблематичным, хотя эти проблемы можно решить, используя другую часть CSS, как описано в этом посте, распаковывающем проблему с сеткой и плавающими элементами, «Редакционные макеты, исключения и сетка CSS».

С учетом всего сказанного, если мы ничего не сделаем, кроме как изменим значение display на grid , мы не увидим большой разницы в нашем макете. Прямые дочерние элементы являются элементами сетки, однако по умолчанию мы получаем сетку с одним столбцом. Сетка всегда имеет один столбец и одну строку. Остальные строки, которые мы можем увидеть после этого, являются неявными строками, т. е. строками, созданными для хранения содержимого.

Набор карточек, выложенных одна под другой в один столбец.
Когда мы создаем контейнер сетки без столбцов, мы получаем сетку с одним столбцом. (Большой превью)

Мы можем начать формировать что-то похожее на сетку, задав значение свойства grid-template-columns . Свойство принимает трек-лист в качестве значения; если я дам ему три дорожки 1fr, мы теперь получим сетку из трех столбцов, и использование свойства gap дает мне интервал между этими картами.

Теперь у нас есть нечто похожее на сетку:

Карточки разложены в три столбца и два ряда
Мы определяем некоторые дорожки столбцов и зазор, чтобы получить очевидную компоновку сетки (большой предварительный просмотр)

У каждого элемента сетки в нашем примере есть собственные дочерние элементы. Карточки имеют верхние и нижние колонтитулы, а также область для основного содержимого карточки. Эти дочерние элементы являются элементами сетки, но их дочерние элементы вернулись к блочному и встроенному макету. Заголовок, область содержимого и нижний колонтитул не имеют ничего общего с сеткой. Это связано с тем, что когда мы меняем значение display на grid , он не наследует, а вместо этого только дочерние элементы становятся элементами сетки; их дети возвращаются к блочной компоновке.

Вложенные сетки

Если на карточке больше содержимого, чем на других карточках, карточки в этом ряду становятся выше. Начальное значение align-items для элементов сетки — stretch . Наши карты растягиваются в полный рост. Однако элементы внутри находятся в обычном блочном и встроенном потоке, поэтому они не растягиваются волшебным образом, чтобы заполнить карту. (Вот почему на изображении выше вы можете видеть, что карточки с меньшим содержанием имеют пробел внизу.)

Если бы мы захотели (чтобы этот нижний колонтитул всегда находился внизу), мы могли бы сделать наш элемент сетки тоже сеткой. В этом случае нам нужна сетка из одного столбца. Затем мы можем определить дорожки строк, задав область, в которой находится div с классом содержимого, размером дорожки 1fr . Это приводит к тому, что он занимает все доступное пространство в контейнере и перемещает нижний колонтитул в нижнюю часть карточки.

См. Pen [display: subgrid is not what we want](https://codepen.io/rachelandrew/pen/PvQzeG) Рэйчел Эндрю.

См. Перьевой дисплей: подсетка — это не то, что нам нужно, Рэйчел Эндрю.

Вы можете делать это вложение сеток столько, сколько вам нужно. На самом деле я не думаю об этом как о вложенности, поскольку мы не создаем здесь вложенные таблицы и обычно используем уже имеющиеся структурные элементы HTML. Мы просто меняем значение display по одному уровню за раз на то, что наиболее подходит для дочерних элементов этого элемента. Это может быть гибкий макет или макет сетки, но чаще всего это будет блочный и встроенный макет. В этом случае нам не нужно ничего делать, потому что это происходит по умолчанию.

Выравнивание верхних и нижних колонтитулов

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

 .cards { display: grid; gap: 20px; grid-template-columns: 1fr 1fr 1fr; } article { display: grid; grid-template-rows: auto 1fr auto; row-gap: 20px; }

Что, если мы хотим, чтобы цвет фона в верхних и нижних колонтитулах выровнялся? Каждая карточка является элементом сетки, но верхние и нижние колонтитулы находятся в сетке элемента. Они не имеют никакого отношения друг к другу, и поэтому мы не можем их выстроить в линию. Здесь было бы неплохо, если бы мы могли как-то наследовать сетку через дочерние элементы.

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

Сегодня у нас нет хорошего решения для этого в браузерах, но оно уже в пути. Функция подсетки CSS Grid Layout Level 2 активирует именно этот шаблон. Вы сможете создать сетку в родительском элементе, а затем выборочно выбрать строки и/или столбцы для использования этой сетки, а не определять новую сетку в child элементе, которая полностью независима от этой сетки.

Обратите внимание, что приведенные ниже примеры работают только в Firefox Nightly на момент написания. Значение подсетки grid-template-columns и grid-template-rows — это новая функция и часть Уровня 2 спецификации CSS Grid. Чтобы попробовать эту функцию, загрузите копию Firefox Nightly.

Вы можете увидеть, как это работает, на изображениях ниже. На первом изображении я создал три дорожки строки на родительском элементе и натянул на них карту. Когда Инспектор сетки Firefox выделяет сетку, вы можете видеть, что строки родителя не связаны со строками, используемыми дочерними элементами.

Изображение сетки из трех столбцов с наложенными дорожками Firefox Grid Inspector.
Проверка сетки с помощью Firefox Grid Inspector показывает, что элементы не отображаются на дорожках родителя. (Большой превью)

Если вместо определения трех строк в дочернем элементе я использую значение подсетки для grid-template-rows , карта теперь использует эти строки в родительском элементе. Вы можете видеть, как они теперь выровнены, и, следовательно, верхние и нижние колонтитулы также выровнены:

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

То, что мы здесь делаем с subgrid, не является новым значением display . Элемент, который является вложенной сеткой, сам является контейнером сетки, так как мы установили для него display: grid . Элементы сетки ведут себя как обычно. Это обычная компоновка сетки — ничем не отличающаяся от исходной вложенной сетки, за исключением того, что (вместо элемента, имеющего собственный размер дорожки строки) она использует дорожки родителя.

 .cards { display: grid; gap: 20px; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: repeat(2,auto 1fr auto); } article { grid-row-end: span 3; display: grid; grid-template-rows: subgrid; }

Это хорошая вещь в подсетке; Если вы уже знаете, как использовать сетку, вам не так уж много предстоит узнать. Вы можете прочитать об остальных деталях в моем предыдущем посте здесь, в Smashing Magazine, «CSS Grid Level 2: Here Comes Subgrid».

Вчера (23 мая 2019 года) подсетка появилась в Firefox Nightly, поэтому у нас есть проверяемая реализация значения подсетки grid-template-columns и grid-template-rows . Пожалуйста, возьмите копию Nightly и попробуйте это. С копией Nightly вы можете увидеть последний пример, работающий в этом CodePen:

См. Перьевой дисплей: подсетка — это не то, что нам нужно, Рэйчел Эндрю.

См. Перьевой дисплей: подсетка — это не то, что нам нужно, Рэйчел Эндрю.

Посмотрите, можете ли вы придумать другие варианты использования, которые решаются с помощью функции подсетки, или, возможно, вещи, которые, по вашему мнению, отсутствуют. Хотя функция доступна только в браузере Nightly, в это время можно внести изменения в спецификацию, если обнаружится какая-то проблема. Итак, сделайте одолжение своему будущему веб-разработчику и попробуйте такие функции, чтобы вы могли внести свой вклад в веб-платформу и сделать ее лучше.

Если вы считаете, что нашли ошибку в реализации Firefox, вы можете взглянуть на основную ошибку реализации на Bugzilla, которая ссылается на связанные проблемы в разделе Зависит от . Если вы не видите свою проблему, создайте как можно более простой сокращенный тестовый пример и сообщите об ошибке. Если вы считаете, что подсетка должна что-то делать для решения варианта использования, и это что-то, что не подробно описано в спецификации, вы можете поднять вопрос в Рабочей группе CSS GitHub для потенциального улучшения.

Что насчет display: contents ?

Если вы следили за этим, вы можете подумать, что display: contents (как описано в предыдущей статье о display ) может решить проблемы, которые пытается решить subgrid — разрешение непрямым дочерним элементам участвовать в макете сетки. Это не так, и наш пример с картами — отличный способ продемонстрировать разницу.

Если вместо того, чтобы сделать нашу карту сеткой с помощью display: grid , мы удалим поле с помощью display: contents , мы получим этот результат в следующем CodePen. (Попробуйте удалить строку display: contents из правил для .card , чтобы увидеть разницу.)

См. Перьевой дисплей: подсетка — это не то, что нам нужно, Рэйчел Эндрю.

См. Перьевой дисплей: подсетка — это не то, что нам нужно, Рэйчел Эндрю.

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

Больше Чтения И Примеров

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

  • Примеры CSS Grid Level 2
  • CSS Grid Level 2: А вот и подсетка
  • Сетки полностью вниз (презентация)
  • Документация MDN для подсетки