CSS 网格:将项目放入 "at least column 2"

CSS grid: place items in "at least column 2"

我有以下 HTML:

<div class="grid">
  <div class="special-1"></div>
  <div class="special-1"></div>

  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
</div>

.special-1 总是在第一列。 .special-2的数量是可变的,由用户数据生成。所以大约:

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 1fr;
}

.special-1 {
  grid-column-start: 1;
}

现在的问题是,我希望 .special-2 至少始终位于第二列。但它也可以显示在第三或第四。无论如何我可以做到这一点吗? grid-column-start: 2; 不起作用,因为它将把它们全部放在第 2 列中,而 none 放在其他列中。所以我基本上想要 grid-column: :not(1)grid-column: 2 | 3 | 4 如果你明白我的意思。有什么想法吗?

你可以像下面这样近似。不过,顺序不一定如愿

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* only 3 explicit clumns */
  grid-auto-columns: 1fr; /* this will size the implicit one */
  grid-auto-flow: dense; /* make sure to fill all the tracks */
  grid-auto-rows: 100px;
  grid-gap: 5px;
}
.special-2 {
  background: red;
}
.special-1 {
  /* place the  #1 outside the explict column
     it will create an implicit column at the start 
  */
  grid-column-end: -4; 
  background: blue;
}
/* place all the #2 in the implicit columns 
   pay attention to the order, they can be scrambled 
*/
.special-2:nth-child(3n+1) {grid-column:1}
.special-2:nth-child(3n+2) {grid-column:2}
.special-2:nth-child(3n+3) {grid-column:3}
<div class="grid">
  <div class="special-1"></div>
  <div class="special-1"></div>

  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
</div>

如果没有元素,以上将只生成 3 列 special-1

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* only 3 explicit clumns */
  grid-auto-columns: 1fr; /* this will size the implicit one */
  grid-auto-flow: dense; /* make sure to fill all the tracks */
  grid-auto-rows: 100px;
  grid-gap: 5px;
}
.special-2 {
  background: red;
}
.special-1 {
  /* place the  #1 outside the explict column
     it will create an implicit column at the start 
  */
  grid-column-end: -4; 
  background: blue;
}
/* place all the #2 in the implicit columns 
   pay attention to the order, they can be scrambled 
*/
.special-2:nth-child(3n+1) {grid-column:1}
.special-2:nth-child(3n+2) {grid-column:2}
.special-2:nth-child(3n+3) {grid-column:3}
<div class="grid">
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
</div>

如果您总是有元素 special-1

,请使用以下内容

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-flow: dense; 
  grid-auto-rows: 100px;
  grid-gap: 5px;
}
.special-2 {
  background: red;
}
.special-1 {
  grid-column: 1; 
  background: blue;
}
.special-2:nth-child(3n+1) {grid-column:2}
.special-2:nth-child(3n+2) {grid-column:3}
.special-2:nth-child(3n+3) {grid-column:4}
<div class="grid">
  <div class="special-1"></div>
  <div class="special-1"></div>

  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
  <div class="special-2"></div>
</div>

Temani Afif 的答案肯定有效,但可扩展性不是很好。在我的用例中,不同的视口大小有一些不同的列数。我最终决定以不同的方式实现这一点。注意:如果在您阅读本文时 CSS Grid Level 2 已经发布,这可以使用 css 子网格轻松解决:caniuse

现在是我的解决方案:我将 html 更改为:

<div class="grid">
  <div class="special-1s"
    <div class="special-1"></div>
    <div class="special-1"></div>
  </div>

  <div class="special-2s">
    <div class="special-2"></div>
    <div class="special-2"></div>
    <div class="special-2"></div>
    <div class="special-2"></div>
    <div class="special-2"></div>
    <div class="special-2"></div>
  </div>
</div>

我的 css 现在看起来有点像下图。我将行强制设置为固定高度,这在我的用例中没问题,并使此解决方案成为可能。

.grid {
  display: flex;
}

.grid > div {
  display: grid;
  grid-auto-rows: 100px;
}

.special-1s {
  flex: 1;
  grid-template-columns: 1fr;
}

.special-2s {
  --columns: 2;
  flex: var(--columns);
  grid-template-columns: repeat(var(--columns), 1fr);

  @media (min-width: 1000px) {
    --columns: 3;
  }

}

通过使用 flex-属性,我可以在 .grid 的宽度上伪造一致的 column-sizes。 --columns 属性 允许我轻松定义额外的 media-queries。 (我实际上比这里显示的要多一些。)