CSS Grid: grid-row / column-start / end VS grid-area + grid-template-area.

Я прочитал руководство по CSS Grid в CSS Tricks, но один важный аспект меня немного смутил.

Кажется, есть два способа решить, сколько ячеек охватывает элемент сетки:

  1. grid-template-area с использованием имен, присвоенных элементам сетки со свойством grid-area
  2. Использование grid-column-start/end и grid-row-start/end

Глядя на мой тестовый код ниже, кажется, что размеры grid items определены в следующем порядке (где значения слева перезаписывают значения справа):

grid-row/column-start/end> grid-template-area> Размер самих элементов

Вопрос

  1. Мой порядок выше в целом правильный?
  2. Есть ли предпочтительный способ (1 или 2 выше) указать размер grid items (т.е. сколько ячеек они охватывают)?

Код

.container {
  display: grid;
  border: 1px solid green;
  grid-template-columns: 120px 120px 120px;
  grid-template-rows: 120px 120px 120px;
  grid-template-areas: "item-1 item-1 item-2" "item-3 item-4 item-4" "item-5 item-6 .";
}

.item-1 {
  border: 1px solid blue !important;
  grid-area: item-1;
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 1;
}

.item-2 {
  grid-area: item-2;
}

.item-3 {
  grid-area: item-3;
}

.item-4 {
  grid-area: item-4;
}

.item-5 {
  grid-area: item-5;
}

.item-6 {
  grid-area: item-6;
}

.box {
  border: 1px solid red;
  display: flex;
  align-items: center;
  text-align: center;
  justify-content: center;
}
<div class="container">
  <div class="item-1 box">Box1</div>
  <div class="item-2 box">Box2</div>
  <div class="item-3 box">Box3</div>
  <div class="item-4 box">Box4</div>
  <div class="item-5 box">Box5</div>
  <div class="item-6 box">Box6</div>
</div>


person Magnus    schedule 17.03.2019    source источник
comment
обратите внимание, что grid-area - это сокращение для всех остальных (grid -.- start grid -.- end) developer.mozilla.org/en-US/docs/Web/CSS/grid-area   -  person Temani Afif    schedule 18.03.2019
comment
Привет @TemaniAfif. Согласно руководству это либо name, либо то, на что вы ссылаетесь: grid-area: дает элементу имя, чтобы на него можно было ссылаться в шаблоне, созданном с помощью свойства grid-template-areas. В качестве альтернативы это свойство можно использовать как еще более короткое сокращение для grid-row-start + grid-column-start + grid-row-end + grid-column-end. В своем вопросе я использую это как первое.   -  person Magnus    schedule 18.03.2019
comment
@TemaniAfif от MDN: для свойства grid-area также можно задать ‹custom-ident›, который действует как имя области, которую затем можно разместить с помощью grid-template-областей.   -  person Magnus    schedule 18.03.2019


Ответы (2)


Кажется, есть два способа решить, сколько ячеек охватывает элемент сетки:

Точнее, есть 3 способа размещения предметов. Из спецификации:

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

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

Обратите внимание, что grid-area - это сокращенное свойство для явного размещения, которое также можно заменить на grid-row-start; grid-column-star; grid-row-end; grid-column-end;

Вот простой пример для иллюстрации:

.grid {
  display:inline-grid;
  grid-template-areas:
    "a b"
    "c d";
  grid-gap:20px;
  border:1px solid;
}
span {
  width:50px;
  height:50px;
  background:red;
}
.one > span {
  grid-area:a;
  grid-row-start:1;
  grid-row-end:3;
  grid-column-start:1;
  grid-column-end:3;
}
.two > span {
  grid-row-start:1;
  grid-row-end:3;
  grid-column-start:1;
  grid-column-end:3;
  grid-area:a;
}
<div class="grid one">
  <span></span>
</div>

<div class="grid two">
  <span></span>
</div>

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

Вы можете проверить второй элемент, и вы получите такое вычисленное значение:

введите здесь описание изображения

Вы не найдете свойство с именем grid-area, как не найдете свойство с именем background, margin, border и т. Д., Потому что все они будут заменены полными обозначениями.


Принимая во внимание размер, вы должны различать размер дорожек и размер предметов. В предыдущем примере мы не определяли какой-либо явный размер, поэтому ширина / высота элемента также будет определять размер дорожки.

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

.grid {
  display:inline-grid;
  grid-template-columns:150px 150px;
  grid-template-areas:
    "a b"
    "c d";
  grid-gap:20px;
  border:1px solid;
}
span {
  width:50px;
  height:50px;
  background:red;
  grid-area:a;
}
.one > span {
  width:400px;
}
.two > span {
  width:100%;
}

.three > span {
  width:200%;
}
<div class="grid one">
  <span></span>
</div>

<div class="grid two">
  <span></span>
</div>

<div class="grid three">
  <span></span>
</div>

Мы определили размер дорожки равным 150px, и если элемент с большим размером, мы просто имеем переполнение. Вы также заметите, как будет вести себя перцетанж, поскольку дорожка будет содержащим блоком элемента сетки, а не контейнером сетки.

Используя инструменты разработчика, вы можете четко видеть следы:

введите здесь описание изображения

Если, например, вы рассматриваете 1fr unit или auto, тогда ширина элемента будет использоваться для определения размеров:

.grid {
  display:inline-grid;
  grid-template-columns:1fr 150px;
  grid-template-areas:
    "a b"
    "c d";
  grid-gap:20px;
  border:1px solid;
}
span {
  width:50px;
  height:50px;
  background:red;
  grid-area:a;
}
.one > span {
  width:400px;
}
<div class="grid one">
  <span></span>
</div>

введите здесь описание изображения

Итак, мы можем выделить 4 случая 1:

  1. размер элемента не определен и размер дорожки не определен: содержимое каждого элемента будет использоваться для определения элемента и размера дорожки.
  2. размер элемента не определен и размер дорожки определен: элемент будет растянут, чтобы заполнить размер дорожки (в зависимости от содержимого элемента может возникнуть переполнение).
  3. размер элемента определен и размер дорожки определен: между ними нет соотношения размеров, мы просто помещаем элемент внутри дорожки. У нас может быть переполнение или пустое пространство внутри дорожки.
  4. размер элемента определен и размер дорожки не определен: размер элемента определяет размер дорожки. В зависимости от случаев он не будет определять его, но будет учитываться при подсчете. (например, здесь: https://stackoverflow.com/a/54639430/8620333)


1: это очень упрощено, чтобы мысли были более ясными. Алгоритм определения размера более сложный.

person Temani Afif    schedule 18.03.2019
comment
Очень полезно, мой друг. Одно замечание: в вашем fr сценарии, на самом деле это не fr, который диктует, что дорожка соответствует элементу. Вместо этого inline-grid делает контейнер того же размера, что и его содержимое. Все, что делает fr, - это посмотреть на размер вашего контейнера, удалить все негибкие элементы (в вашем случае 150 + 20), затем сделать первый столбец долей того, что осталось (в вашем случае доля равна 1/1, т.е. 100%). Результат можно увидеть, изменив inline-grid на grid в вашем примере. - person Magnus; 18.03.2019
comment
Ваша точка зрения о том, что grid-area является сокращенной собственностью, ответила на мой вопрос. Затем он просто возвращается к порядку в блоке css, как вы говорите. Примечание. Мое первоначальное предположение о том, что ширина и высота элемента имеют самый низкий приоритет, было неверным. Фактически, ширина и высота элемента превосходят все свойства сетки CSS. Если мы зафиксируем ширину и высоту элемента, элемент не будет охватывать ячейки сетки. После установки размер элемента не изменится. - person Magnus; 18.03.2019
comment
Одна вещь, которая немного сложнее, - это ваш первый пример с двумя красными квадратами, каждый с фиксированной высотой и шириной. Мы знаем, что часть inline свойства display - это то, что не дает контейнеру растягиваться на всю ширину его родительского содержащего блока. Что труднее понять, так это то, что высота дорожки становится высотой элемента ТОЛЬКО при использовании шаблона. В основном, остальные строки становятся равными 0 по высоте, а зазор в 20 пикселей внизу сохраняется ..... 1/2 - person Magnus; 18.03.2019
comment
.... При применении свойств сетки отдельного элемента высота каждой строки становится одинаковой, полностью покрывая высоту элемента. Я понятия не имею, почему они отличаются. Я предполагаю, что в сценарии шаблона мы сообщаем браузеру, что на самом деле будет две строки. Он просто не показывает вторую строку, потому что не хватает элементов. В другом сценарии (без шаблона) браузер каким-то образом предполагает, что будет две строки и два столбца, затем сокращает общую высоту контейнера до соответствия высоте элемента и делает каждую строку одинаковой высоты. - person Magnus; 18.03.2019
comment
Ах, браузер определяет количество строк из свойства grid-row-end. Хорошо, думаю, теперь я все понимаю. PS: Просто чтобы указать на одну вещь, которую вы, вероятно, уже знаете, но в вашем первом примере с двумя квадратами единственная причина, по которой они по-разному рисуют на экране, связана с зазором сетки (как и во втором сценарии, это происходит по шаблону ). В первом сценарии он определяет количество строк на основе ваших индивидуальных свойств элемента, а затем устанавливает одинаковую высоту в каждой строке (и ширину в каждом столбце, если вы сохраняете сетку равной inline-grid). - person Magnus; 18.03.2019
comment
Наконец, отсутствует случай 4-го размера: 4) Размер элемента определен, размер дорожки не определен. Это то, что относится к вашему первому примеру с двумя квадратами. Я набрал ответ на своем компьютере, но он слишком длинный, чтобы публиковать его здесь. Таким образом, это зависит от inline-grid и grid, а также от того, размещаете ли вы элементы с named areas (т.е. template-areas) или делаете line-based размещение. - person Magnus; 18.03.2019
comment
@ Магнус, ты почти понял. единственная разница между grid и inline-grid - это поведение при усадке. Таким образом, сетка будет иметь полную ширину, тогда 1fr будет долей от оставшегося пространства после удаления 150 пикселей и одного пробела. Для встроенной сетки 1fr будет минимальным размером, необходимым для размещения элемента (в этом разница), потому что 1fr - это minmax (auto, 1fr). Итак, для встроенной сетки авто выполняет свою работу. Сделайте так, чтобы ваш элемент имел grid-column:1/-1, и вы увидите разницу. В этом случае вы сделаете его содержащимся в 1fr и 150px. - person Temani Afif; 18.03.2019
comment
@Magnus в первом примере, поскольку я не определил размер дорожки и в b, c, d нет элемента, они будут пустыми, НО вы увидите пробел, и вы увидите, что b будет иметь ширину: 0, но той же высоты, что и a и c d height: 0 и той же ширины, что и a (потому что это сетка). Когда я поместил свой элемент во весь пояс, я также закрыл зазор, и снова здесь играет сжатие до размера, и, поскольку размер не установлен, по умолчанию все они (a b c d) будут иметь одинаковую ширину / высоту . Тот, который должен был содержать наш элемент - person Temani Afif; 18.03.2019
comment
@Magnus Да, забудьте о 4-м случае (я собирался спать: p) Я отредактирую свой ответ ... и в основном, как вы сказали, размер дорожки будет зависеть от элемента, и я использовал встроенную сетку, чтобы показать это. Если мы рассмотрим grid, он будет другим, потому что при расчете будет учитываться полная ширина, поэтому я решил inline, чтобы упростить понимание, и, как я сказал внизу, на самом деле это более сложно ... вот еще один вопрос, где Я подробно описал расчет в случае grid, где мы не устанавливаем размер трека stackoverflow.com/a/54639430/8620333 ( 4-й случай) - person Temani Afif; 18.03.2019
comment
@Magnus - еще один пример, чтобы лучше понять fr, особенно тот факт, что он равен minmax(auto,1fr): stackoverflow.com/a/54129099/8620333 - person Temani Afif; 18.03.2019

С помощью свойства grid-template-areas вы ограничены прямоугольными областями сетки.

Благодаря свойствам grid-column-* и grid-row-* у вас больше гибкости.


С grid-template-areas вы можете создавать области сетки только внутри явной сетки.

С grid-column-* и grid-row-* вы можете выйти за пределы явной сетки, создавая области сетки в неявной сетке.

person Michael Benjamin    schedule 18.03.2019
comment
Спасибо, Майкл. Я прочитал другой ваш пост о неявной и явной сетке, достоверная информация. Связанный дополнительный вопрос: возможно ли появление неявной сетки только тогда, когда явная сетка меньше контейнера. В тестах, которые я запускал только что, казалось, что неявные треки содержались в контейнере. - person Magnus; 18.03.2019
comment
Дорожки сетки (явные и неявные) существуют внутри контейнера. Контейнер должен расширяться, чтобы вместить новые гусеницы. Неявные строки и столбцы представляют контейнер сетки, добавляющий новые дорожки внутри себя для размещения областей сетки, расположенных за пределами явной сетки. - person Michael Benjamin; 18.03.2019