CSS网格自动添加不需要的列

6
尝试使用不同的类名通过CSS网格将项目分组为两行。 直到“红色”组中没有超过预定义行数(此处为3),它才能正常工作。
我是否可以将第4个“红色”元素放在新行中?
如果只有3个“红色”元素,则一切正常。

ul {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

.blue {
  background-color: blue;
}

.red {
  background-color: red;
  grid-row-start: 5;
}
<ul>
  <li class="blue">
    <h2>1</h2>
  </li>
  <li class="red">
    <h2>2</h2>
  </li>
  <li class="blue">
    <h2>3</h2>
  </li>
  <li class="blue">
    <h2>4</h2>
  </li>
  <li class="red">
    <h2>5</h2>
  </li>
  <li class="red">
    <h2>6</h2>
  </li>
  <!-- If you delete this (or any other "red") "li" element then it's working fine -->
  <li class="red">
    <h2>7</h2>
  </li>
  <li class="blue">
    <h2>8</h2>
  </li>
</ul>


我不明白,第四列是因为它是隐式网格的一部分才存在的。一旦创建,它就不能被忽略。 - Paulie_D
谢谢!我现在搜索了什么是隐式网格。我的问题就是因为它。但是我该如何将我的内容从隐式网格放到显式网格中呢?“nth-child()”方法不好用,因为“红色”和“蓝色”元素的顺序可能会变化。您能否提出解决这个问题的不同方法? - Arva Istvan
1个回答

9
您正在使用 grid-row-start: 5 指定所有 red 元素进入第五行。是的,红色元素被放置在第五行,但这并不立即可见,因为您没有指定一个显式的行定义(例如,使用 grid-template-rows)。

隐式行

您可以使用像 grid-auto-rows: 50px 这样的方式定义隐式行定义,并查看 red 元素实际上位于第五行:

ul {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-auto-rows: 50px; /* specify row height */
  list-style: none; /* remove bullets */
  padding: 0; /* remove default ul padding */
}

.blue {
  background-color: blue;
}

.red {
  background-color: red;
  grid-row-start: 5;
}

li {
  border: 1px solid #bbb; /* border for illustration */
}
<ul>
  <li class="blue">
    <h2>1</h2>
  </li>
  <li class="red">
    <h2>2</h2>
  </li>
  <li class="blue">
    <h2>3</h2>
  </li>
  <li class="blue">
    <h2>4</h2>
  </li>
  <li class="red">
    <h2>5</h2>
  </li>
  <li class="red">
    <h2>6</h2>
  </li>
  <!-- If you delete this (or any other "red") "li" element then it's working fine -->
  <li class="red">
    <h2>7</h2>
  </li>
  <li class="blue">
    <h2>8</h2>
  </li>
</ul>

隐式列

现在你的问题是为什么第 四个 红色项目与同一行 - 因为你已经将它们全部放在同一个第五行中。使用自动宽度创建了一个 隐式网格列 - 你可以使用 grid-auto-columns 控制此宽度:

ul {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-auto-rows: 50px; /* specify row height */
  grid-auto-columns: 100px; /* specify column width */
  list-style: none; /* remove bullets */
  padding: 0; /* remove default ul padding */
}

.blue {
  background-color: blue;
}

.red {
  background-color: red;
  grid-row-start: 5;
}

li {
  border: 1px solid #bbb; /* border for illustration */
}
<ul>
  <li class="blue">
    <h2>1</h2>
  </li>
  <li class="red">
    <h2>2</h2>
  </li>
  <li class="blue">
    <h2>3</h2>
  </li>
  <li class="blue">
    <h2>4</h2>
  </li>
  <li class="red">
    <h2>5</h2>
  </li>
  <li class="red">
    <h2>6</h2>
  </li>
  <!-- If you delete this (or any other "red") "li" element then it's working fine -->
  <li class="red">
    <h2>7</h2>
  </li>
  <li class="blue">
    <h2>8</h2>
  </li>
</ul>


解决方案

您可以这样做来分组

  • 红色项目的order:1设置为比蓝色项目晚,这样它们就会排在蓝色项目之后。

  • 使用grid-column:1将第一个红色元素设置为第一列,其余元素将使用grid-column:auto自动放置。

请参见以下演示:

ul {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  list-style: none; /* remove bullets */
  padding: 0; /* remove default ul padding */
}

.blue {
  background-color: blue;
}

.red {
  background-color: red;
  order: 1; /* red items have higher order */
}

.red { /* first red element into first column */
  grid-column: 1;
}

.red ~ .red { /* subsequent red elements auto-placed */
  grid-column: auto;
}

li {
  border: 1px solid #bbb; /* border for illustration */
}
<ul>
  <li class="blue">
    <h2>1</h2>
  </li>
  <li class="red">
    <h2>2</h2>
  </li>
  <li class="blue">
    <h2>3</h2>
  </li>
  <li class="blue">
    <h2>4</h2>
  </li>
  <li class="red">
    <h2>5</h2>
  </li>
  <li class="red">
    <h2>6</h2>
  </li>
  <!-- If you delete this (or any other "red") "li" element then it's working fine -->
  <li class="red">
    <h2>7</h2>
  </li>
  <li class="blue">
    <h2>8</h2>
  </li>
</ul>

显式网格 vs 隐式网格


显式网格

显式网格 是指您使用 grid-template-columnsgrid-template-rowsgrid-template-areas 以及相关的缩写属性 来定义的网格,以下是来自W3C文档的摘录:

显式网格(W3C)

grid-template-rows、grid-template-columns 和 grid-template-areas 这三个属性共同定义了网格容器的显式网格。由于放置在显式网格外部的网格项可能会使最终的网格变得更大,在这种情况下,将创建隐式轨道,这些隐式轨道将由 grid-auto-rows 和 grid-auto-columns 属性来设置大小。


下面是一个示例,展示了一个显式2x2网格,稍后我们将回到它:

.wrapper {
  display: grid;
  grid-template-columns: 100px 100px;
  grid-template-rows: 50px 50px;
  grid-gap: 5px;
}
/* styles */
.wrapper > div { border: 1px solid cadetblue; background: lightblue; display: flex; justify-content: center; align-items: center;}
<div class="wrapper">
  <div>1</div><div>2</div><div>3</div><div>4</div>
</div>

隐式网格

如果你在网格容器内部但在显式网格定义之外有更多内容或元素,那么这部分就是所谓的隐式网格

你可以使用grid-auto-rowsgrid-auto-columns属性来控制隐式网格的大小。

隐式网格 (W3C)

grid-template-rowsgrid-template-columnsgrid-template-areas属性定义了形成显式网格的固定轨道数。当网格项被定位在这些边界之外时,网格容器通过添加隐式网格线来生成隐式网格轨道。这些线与显式网格一起形成隐式网格。grid-auto-rowsgrid-auto-columns属性调整隐式网格轨道的大小。


如果你在上面的例子中有更多的网格项,你会看到创建的隐式行 - 这些行可以使用grid-auto-rows属性进行调整大小:

.wrapper {
  display: grid;
  grid-template-columns: 100px 100px;
  grid-template-rows: 50px 50px;
  grid-gap: 5px;
  grid-auto-rows: 25px; /* size of implicit rows */
}
/* styles */
.wrapper > div { border: 1px solid cadetblue; background: lightblue; display: flex; justify-content: center; align-items: center;}
<div class="wrapper">
  <div>1</div><div>2</div><div>3</div><div>4</div>
  <div>5</div><div>6</div><div>7</div><div>8</div>
</div>

要查看创建的隐式列,可以尝试将某些“网格项”放置在第二列之外-可以使用 grid-auto-columns 属性调整这些行的大小。观察新列是如何创建以及网格的行为表现:

.wrapper {
  display: grid;
  grid-template-columns: 100px 100px;
  grid-template-rows: 50px 50px;
  grid-gap: 5px;
  grid-auto-rows: 25px; /* size of implicit rows */
  grid-auto-columns: 25px; /* size of implicit columns */
}

div:nth-child(5), div:nth-child(6) {
  grid-column: 3; /* place in thrid column */
}

/* styles */
.wrapper > div { border: 1px solid cadetblue; background: lightblue; display: flex; justify-content: center; align-items: center;}
<div class="wrapper">
  <div>1</div><div>2</div><div>3</div><div>4</div>
  <div>5</div><div>6</div><div>7</div><div>8</div>
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接