如何在CSS网格布局中指定布局顺序?

3

所以我有一个网格来显示页面上的某个部分,如下所示。基本上,它的布局如下:

[1] [ Item 1 ] [2] [ Item 2 ]  
[3] [ Item 3 ] [4] [ Item 4 ]

当屏幕通过媒体查询变窄以适应移动设备时,它会变成这样:

[1] [ Item 1 ]  
[2] [ Item 2 ]  
[3] [ Item 3 ]  
[4] [ Item 4 ]

这很完美,正是我所需要的。我的问题是,在第一个示例中,我需要它像这样进行:

[1] [ Item 1 ] [3] [ Item 3 ]  
[2] [ Item 2 ] [4] [ Item 4 ]

现在在我的实际代码中,有很多网格项,因此我希望它首先排列第一列,然后是第二列,而不是逐行填充。我可以在HTML中物理更改网格项的顺序,但在移动屏幕上,顺序会混乱。我查看了 grid-auto-flow,但无法确定它是否符合我的需求。解决方案可能非常简单,但我认为我已经离这个项目很近了,很难退一步并解决它。任何帮助都将不胜感激!

.grid {
  display: grid;
  grid-template-columns: 48px 1fr 48px 1fr;
  column-gap: 12px;
  align-items: center;
  justify-content: center;
  background-color: orange;
  border: 1px solid black;
}

.grid-item {
  padding: 16px;
  border: 1px solid black;
  font-size: 12px;
  background-color: aliceblue;
}
<section class="grid">
  <div class="grid-item">1</div>
  <div class="grid-item">Item 1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">Item 2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">Item 3</div>
  <div class="grid-item">4</div>
  <div class="grid-item">Item 4</div>
</section>


1
要填充这样的列,您需要指定行数,我知道您可能不知道,但这就是列流的工作方式。 - Paulie_D
话虽如此,你可能可以使用nth选择器做些什么。 - Paulie_D
@Paulie_D 是的,完全正确,这种情况下我将知道每个页面的行数,所以那个答案非常完美!非常感谢! - Jamie Doyle
将默认的网格自动流从行更改为列:grid-auto-flow: column; - Carol McKay
2个回答

0

我已经更改了您的布局以实现您想要的效果。就像您所说,有很多解决方案,这是我的解决方案!希望能帮到您。

总之,我使用了 display flex 而不是 grid 将布局分成两列(移动优先策略),在移动屏幕上将它们打印在彼此下面,然后通过媒体查询更改为并排显示。

这是我的代码:

.flex {
  background-color: orange;
  border: 1px solid black;
}
.grid-item {
  padding: 16px;
  border: 1px solid black;
  font-size: 12px;
  background-color: aliceblue;
}
.row {
  display: flex;
  justify-content: start;
  align-items: center;
}
.row div {
  padding: 16px;
  border: 1px solid black;
  font-size: 12px;
  background-color: aliceblue;
  text-align: center;
}
.row .counter {
  max-width: 48px;
}
.row .item {
  flex: 1;
}

@media(min-width: 768px) {
  .flex {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .column {
    flex: 1;
  }
}
<section class="flex">
  <div class="column">
    <div class="row">
      <div class="counter">1</div>
      <div class="item">Item 1</div>
    </div>
    <div class="row">
      <div class="counter">2</div>
      <div class="item">Item 2</div>
    </div>
  </div>
  <div class="column">
    <div class="row">
      <div class="counter">3</div>
      <div class="item">Item 3</div>
    </div>
    <div class="row">
      <div class="counter">4</div>
      <div class="item">Item 4</div>
    </div>
  </div>
</section>


0

如果想要改变顺序,可以使用order ;)

通过使用nth-child(n)选择器和你的HTML代码,可能会是这样:

.grid {
  display: grid;
  grid-template-columns: 48px 1fr 48px 1fr;
  column-gap: 12px;
  align-items: center;
  justify-content: center;
  background-color: orange;
  border: 1px solid black;
}

.grid-item {
  padding: 16px;
  border: 1px solid black;
  font-size: 12px;
  background-color: aliceblue;
}

.grid-item:nth-child(4n) ,/* catch 4, 8, ..*/
.grid-item:nth-child(4n - 1)/*, catch 3,7,...)*/
 {
  order: 1;
  color:green;
  font-weight:bold;
}
<section class="grid">
  <div class="grid-item">1</div>
  <div class="grid-item">Item 1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">Item 2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">Item 3</div>
  <div class="grid-item">4</div>
  <div class="grid-item">Item 4</div>
</section>

资源

对于未知数量的项目(如果您有一个已知的最大可能数量),您可以使用:nth-last-child():first-child选择器准备几个规则来测试物品的数量,以将x个项目放入不同的列中。
例如,有8个项目(16)。

.grid {
  display: grid;
  grid-template-columns: 48px 1fr 48px 1fr;
  column-gap: 12px;
  align-items: center;
  justify-content: center;
  background-color: orange;
  border: 1px solid black;
  grid-auto-flow:row dense;
}

.grid-item {
  padding: 16px;
  border: 1px solid black;
  font-size: 12px;
  background-color: aliceblue;
}

/* start filling 2 columns of the grid */
.grid-item:nth-child(odd)  {
  grid-column:1;
}
.grid-item:nth-child(even)  {
  grid-column:2;
}

/* if 8 items (16) , send odds and evens them to their next respective columns */
.grid-item:nth-last-child(16):first-child~:nth-child(8) ~ .grid-item:nth-child(odd)  {
  grid-column:3;
}
.grid-item:nth-last-child(16):first-child~:nth-child(8) ~ .grid-item:nth-child(even)  {
  grid-column:4;
}
<section class="grid">
  <div class="grid-item">1</div>
  <div class="grid-item">Item 1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">Item 2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">Item 3</div>
  <div class="grid-item">4</div>
  <div class="grid-item">Item 4</div>  
  <div class="grid-item">5</div>
  <div class="grid-item">Item 5</div>
  <div class="grid-item">6</div>
  <div class="grid-item">Item 6</div>
  <div class="grid-item">7</div>
  <div class="grid-item">Item 7</div>
  <div class="grid-item">8</div>
  <div class="grid-item">Item 8</div>
</section>

从上面的代码片段中,你可以重复使用规则更新.grid-item:nth-last-child(XX):first-child~:nth-child(X),并根据其子项数量进行测试。


Javascript 也可以很容易地帮助将元素设置到特定的列中。

let item = document.querySelectorAll(".grid-item");
i = 0;
let evenodd = (item.length/2)%2; // to make first col higher if amount of item not balanced
for (let e of document.querySelectorAll(".grid-item")) {
  i++;
  if (i >  item.length / 2 + evenodd ) {
    let pos = i;
    let odd = pos % 2;
    if (odd == 1) {
      e.classList.toggle("col3");
    } else {
      e.classList.toggle("col4");
    }
  }
}
.grid {
  display: grid;
  grid-template-columns: 48px 1fr 48px 1fr;
  column-gap: 12px;
  align-items: center;
  justify-content: center;
  background-color: orange;
  border: 1px solid black;
  grid-auto-flow: row dense;
}

.grid-item {
  padding: 16px;
  border: 1px solid black;
  font-size: 12px;
  background-color: aliceblue;
}

.grid-item:nth-child(odd) {
  grid-column: 1;
}

.grid-item:nth-child(even) {
  grid-column: 2;
}


/* class will beassigned via javascript */

.grid-item.col3 {
  grid-column: 3;
}

.grid-item.col4 {
  grid-column: 4;
}
<section class="grid">
  <div class="grid-item">1</div>
  <div class="grid-item">Item 1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">Item 2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">Item 3</div>
  <div class="grid-item">4</div>
  <div class="grid-item">Item 4</div>
  <div class="grid-item">5</div>
  <div class="grid-item">Item 5</div>
  <div class="grid-item">6</div>
  <div class="grid-item">Item 6</div>
  <div class="grid-item">7</div>
  <div class="grid-item">Item 7</div>
  <div class="grid-item">8</div>
  <div class="grid-item">Item 8</div>
  <div class="grid-item">9</div>
  <div class="grid-item">Item 9</div>
</section>


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