Удалите широкие пробелы в сетке CSS

Я сделал дизайн с использованием CSS-сеток, которые дали мне неожиданное пространство между строками. Я воспроизвел свою проблему со следующим кодом:

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}
article {
  background: red;
}
.item1 {
  height: 30px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 2;
}
.item2 {
  height: 100px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 2;
  grid-row-end: 3;
}
.item3 {
  height: 300px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 3;
  grid-row-end: 4;
}
.item4 {
  height: 490px;
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 5;
}
.item5 {
  height: 160px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 4;
  grid-row-end: 6;
}
.item6 {
  height: 520px;
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 5;
  grid-row-end: 7;
}
.item7 {
  height: 300px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 6;
  grid-row-end: 7;
}
<main>
  <article class="item1"></article>
  <article class="item2"></article>
  <article class="item3"></article>
  <article class="item4"></article>
  <article class="item5"></article>
  <article class="item6"></article>
  <article class="item7"></article>
</main>

здесь вы можете увидеть дополнительный пробел в верхней части нижних элементов.

Я нашел аналогичный вопрос -- Почему CSS Grid layout добавляет дополнительные пробелы между ячейками? -- где дополнительный пробел был вызван цифрами и решен с помощью display: flex по цифрам, но это не сработало для мне.

есть идеи?


EDIT:

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

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}
article {
  background: red;
}
article div {
  background: blue;
}
.item1 {
  grid-column-start: 1;
  grid-column-end: span 1;
  grid-row-start: 1;
  grid-row-end: span 1;
}
.item1 div {
  height: 30px;
}
.item2 {
  grid-column-start: 1;
  grid-column-end: span 1;
  grid-row-start: 2;
  grid-row-end: span 1;
}
.item2 div {
  height: 100px;
}
.item3 {
  grid-column-start: 1;
  grid-column-end: span 1;
  grid-row-start: 3;
  grid-row-end: span 1;
}
.item3 div {
  height: 300px;
}
.item4 {
  grid-column-start: 2;
  grid-column-end: span 1;
  grid-row-start: 1;
  grid-row-end: span 4;
}
.item4 div {
  height: 490px;
}
.item5 {
  grid-column-start: 1;
  grid-column-end: span 1;
  grid-row-start: 4;
  grid-row-end: span 2;
}
.item5 div {
  height: 160px;
}
.item6 {
  grid-column-start: 2;
  grid-column-end: span 1;
  grid-row-start: 5;
  grid-row-end: span 2;
}
.item6 div {
  height: 520px;
}
.item7 {
  grid-column-start: 1;
  grid-column-end: span 1;
  grid-row-start: 6;
  grid-row-end: span 1;
}
.item7 div {
  height: 300px;
}
<main>
  <article class="item1"><div></div></article>
  <article class="item2"><div></div></article>
  <article class="item3"><div></div></article>
  <article class="item4"><div></div></article>
  <article class="item5"><div></div></article>
  <article class="item6"><div></div></article>
  <article class="item7"><div></div></article>
</main>

здесь вы можете увидеть дополнительный пробел в красном цвете. Высоты на содержимом div здесь только для имитации реального содержания статей, поэтому они не могут быть изменены в реальном примере (они оставлены по умолчанию в реальном коде). Основываясь на предварительных ответах, я попытался grid-auto-rows свойство, но это не решило проблему.

3 ответов


у вас есть контейнер сетки с тремя явными столбцами и желобами 10px:

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

нет определенных строк. Все строки неявны и принимают высоту содержимого (потому что значение по умолчанию контейнера сетки grid-auto-rows: auto).

внутри этого контейнера находятся семь элементов сетки, которые расположены с помощью линейное размещение.

давайте разберем это на отдельные части.


пункт 1

.item1 {
    height: 30px;
    grid-column-start: 1;
    grid-column-end: 2;
    grid-row-start: 1;
    grid-row-end: 2;
}

enter image description here

достаточно просто. Элемент 1 охватывает первый столбец и первую строку. Это 30px в высоту, которая устанавливает высоту строки.


пункт 2

.item2 {
    height: 100px;
    grid-column-start: 1;
    grid-column-end: 2;
    grid-row-start: 2;
    grid-row-end: 3;
}

enter image description here

опять же, довольно просто. Пункт 2 охватывает первый столбец и вторую строку. Это 100px в высоту, которая устанавливает высоту строки.


пункт 3

.item3 {
    height: 300px;
    grid-column-start: 1;
    grid-column-end: 2;
    grid-row-start: 3;
    grid-row-end: 4;
}

enter image description here

как и два пункта выше, пункт 3 ясен и прост. Она проходит через первую колонку и третий ряд. Это 300px в высоту, которая устанавливает высоту строки.

теперь это начинает становиться немного сложнее...


пункт 4

.item4 {
    height: 490px;
    grid-column-start: 2;
    grid-column-end: 3;
    grid-row-start: 1;
    grid-row-end: 5;
}

enter image description here

пункт 4 имеет значение в общей сложности четыре строки:

grid-row-start: 1 / grid-row-end: 5

он имеет высоту 490px.

но элементы 1, 2 и 3 установлены в общей сложноститри строки:

grid-row-start: 1 / grid-row-end: 4

...и их общая высота: 430px (30px + 100px + 300px)

таким образом, пункт 4 создает новую строку с высотой 30px (490px - 430px - 30px сетки пробелов строк).


пункт 5

.item5 {
    height: 160px;
    grid-column-start: 1;
    grid-column-end: 2;
    grid-row-start: 4;
    grid-row-end: 6;
}

enter image description here

пункт 5 имеет высоту 160px и установлен для охвата двух строк. Он начинается с четвертого числа. строка (которая была создана по пункту 4) и создает новую пятую строку.

потому что высота строк установлена в auto, каждая строка получает равное распределение высоты элемента сетки, как определено в спецификации для областей сетки, которые охватывают несколько дорожек. Это делает строки 4 и 5 каждый 80px высотой.

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


пункт 6

.item6 {
    height: 520px;
    grid-column-start: 2;
    grid-column-end: 3;
    grid-row-start: 5;
    grid-row-end: 7;
}

enter image description here

пункт 6 начинается с строки 5. Как объяснялось выше (см. важно), строка 5 больше не может быть установлена на пункт 4 из-за grid-auto-rows: auto в области сетки элемента 5. это приводит к разрыву 50px выше пункта 6.

80px height of row 4 - 30px excess of Item 4 = 50px

но теперь пункт 6 добавляет к высоте 80px строки 5, созданной пунктом 5. второй разрыв был создан.


пункт 7

.item7 {
    height: 300px;
    grid-column-start: 1;
    grid-column-end: 2;
    grid-row-start: 6;
    grid-row-end: 7;
}

enter image description here

высота последних двух строк определяется следующими тремя факторами:

  • высота пункта 5, которая составляет 80px в строке 5
  • высота элемента 6, которая составляет 520px, которая сочетается с высотой строки 5 и охватывает две строки
  • высота деталя 7, который 300px и охватывает 1 строку

по той же причине, что сетка строка строки 5 находится на расстоянии от пункта 4, сетка строка строки 6 пробелы от пункта 5:auto высота строки распределяет высоту элемента 6 между строками, которые он покрывает.


Решение

вместо установки высоты элементов сетки, рассмотреть возможность установки grid-auto-rows к чему-то вроде 10px. Тогда используйте span ключевое слово для создания областей сетки вы хотеть.

так вместо этого...

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

.item5 {
  height: 160px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 4;
  grid-row-end: 6;
}

рассмотрим следующий пример:

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 10px; /* new */
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

.item5 {
  /* height: 160px; */
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 4;     /* this would have to be adjusted, as well */
  grid-row-end: span 16; /* new */
}

этот подход описан здесь: CSS-только макет кладки, но с элементами, упорядоченными по горизонтали


по-видимому, это не та же проблема ( в Почему CSS Grid layout добавляет дополнительные пробелы между ячейками? )

дело в том, что ты задание height столбца, заставляющего его не заполнять оставшиеся и испортить grid, так как вы указываете, где он должен start и end на grid-column и grid-row установка height to auto для правых элементов столбца исправит вашу проблему,

enter image description here

я считаю, почему grid ведет себя так, потому что вы не установили grid-template-rows на grid, строки имеют высоту своего содержимого в первых столбцах,

я думаю, что вы не должны установить высоту grid-items и использовать grid-template-rows и если вы не удовлетворены с высоты с height:auto, может быть, вам стоит подумать о переработке вашего grid-row-start и grid-row-end

i надеюсь, это решит вашу проблему или, по крайней мере, даст вам представление о том, как ее исправить.

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}
article {
  display: flex;
  background: red;
}
.item1 {
  height: 30px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 2;
}
.item2 {
  height: 100px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 2;
  grid-row-end: 3;
}
.item3 {
  height: 300px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 3;
  grid-row-end: 4;
}
.item4 {
  height: auto;
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 5;
}
.item5 {
  height: 160px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 4;
  grid-row-end: 6;
}
.item6 {
  height: auto;
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 5;
  grid-row-end: 7;
}
.item7 {
  height: 300px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 6;
  grid-row-end: 7;
}
<main>
  <article class="item1"></article>
  <article class="item2"></article>
  <article class="item3"></article>
  <article class="item4"></article>
  <article class="item5"></article>
  <article class="item6"></article>
  <article class="item7"></article>
</main>

разрыв происходит от просчет высоты вы к контейнерам. Вы должны иметь в виду 10px водостоки, через которые проходит ваш элемент element.

чтобы держать его жидким, вы можете использовать min-height вместо height и использовать grid-template-rows или grid-auto-rows как-то поставил min-height к строк.

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