css 网格布局如何工作

How does css grid layout works

我想知道 Css 网格布局如何。在我尝试下面的操作之前,我以为我已经接近理解它了。

我认为这会使项目 5 排在项目 3 之后,因为它在网格中没有定义位置,但它却排在项目 3 之后,它背后的行为是什么?

https://codepen.io/anon/pen/GOPvXO\

html, body {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.wrapper{
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 50px 50px 50px;
}

.wrapper div{
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    color: white;
}

.wrapper div:nth-child(1){
  background-color: blue; 
  grid-column-start: 1;
  grid-column-end: 3;
}
.wrapper div:nth-child(2){
  background-color: red;
}
.wrapper div:nth-child(3){
  background-color: green;
  grid-column-start: 2;
  grid-column-end: 3;
}
.wrapper div:nth-child(4){
  background-color: lightblue;
    grid-column-start: 2;
    grid-row-end: 4;
}
.wrapper div:nth-child(5){
  background-color: pink;
}
.wrapper div:nth-child(6){
  background-color: lightgreen;
}
<div class="wrapper">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>

W3C docs and this article 可以帮助您理解为什么网格会这样工作。

让我们根据文档中的8.5 Grid Item Placement Algorithm看一下grid-items是如何放置的:

0。生成匿名网格项

没有匿名项 - none 生成了网格项

1.定位任何非自动定位的内容。

在此步骤中,仅 元素 4 被定位

grid-column-start: 2; /* second column, span 1 */
grid-row-end: 4;      /* third row, span 1 */

2。处理锁定到给定行的项目。

没有项目锁定到特定行,所以none定位

3。确定隐式网格中的列。

您的显式网格中的列数是 3。 没有项目需要超过 3 列 - 元素 1,2 和 4 不需要超过 3,其余所有都没有指定明确的列,这意味着隐式网格中的列数是 3

4.放置剩余的网格项。

在你的例子中,算法根据默认的“稀疏”包装工作:

Set the column-start line of its placement to the earliest (smallest positive index) line index that ensures this item’s grid area will not overlap any occupied grid cells and that is past any grid items previously placed in this row by this step.

此时您还有五个元素需要定位:1、2、3、5 和 6。 自动放置光标现在位于最开始的行和列,即第 1 行和第 1 列。逐步说明如何放置所有剩余项目:

  • Position element 1 (definite column position) in row 1, col 1-2, Auto-placement cursor moves to row 1 column 3.
  • 第 1 行第 3 列中的 元素 2(双轴自动定位),自动放置光标移动到第 2 行第 1 列,因为只有 3 列。
  • 位置元素3(确定列位置)在第2行第2列,自动放置光标移动到第2行第3列
  • 第 2 行第 3 列中的第 元素 5(双轴自动定位),自动放置光标移动到第 3 行第 1 列。
  • 定位元素6(双轴自动定位),自动放置光标在第3行第3列。

如果你想让元素5排在元素3后面,你有两种方法:

解决方案 1:设置 grid-auto-flow: dense;

这样在放置 元素 3 后 自动放置光标将转到隐式网格中最开始的行和列行 - 这是第 2 行第 1 列。

元素 6 也会发生同样的情况,因此它将被放置在第 2 行第 3 列中。

html,
body {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.wrapper {
  display: grid;
  grid-auto-flow: dense;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 50px 50px 50px;
}

.wrapper div {
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  color: white;
}

.wrapper div:nth-child(1) {
  background-color: blue;
  grid-column-start: 1;
  grid-column-end: 3;
}

.wrapper div:nth-child(2) {
  background-color: red;
}

.wrapper div:nth-child(3) {
  background-color: green;
  grid-column-start: 2;
  grid-column-end: 3;
}

.wrapper div:nth-child(4) {
  background-color: lightblue;
  grid-column-start: 2;
  grid-row-end: 4;
}

.wrapper div:nth-child(5) {
  background-color: pink;
}

.wrapper div:nth-child(6) {
  background-color: lightgreen;
}
<div class="wrapper">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>

解决方案 2:明确定义元素 3 的行

这样 元素 3 将被放置在算法的第 1 步,第 4 步将像这样:

  • Position element 1 (definite column position) in row 1, col 1-2, Auto-placement cursor moves to row 1 column 3.
  • 第 1 行第 3 列中的 元素 2(双轴自动定位),自动放置光标移动到第 2 行第 1 列,因为只有 3 列。
  • Position element 5 (auto-position on both axis) in row 2, col 1, 自动放置光标移动到第3行第3列,因为第2行第2列是已被占用
  • 定位元素6(双轴自动定位),自动放置光标移动到第3行第1列。

html,
body {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.wrapper {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 50px 50px 50px;
}

.wrapper div {
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  color: white;
}

.wrapper div:nth-child(1) {
  background-color: blue;
  grid-column-start: 1;
  grid-column-end: 3;
}

.wrapper div:nth-child(2) {
  background-color: red;
}

.wrapper div:nth-child(3) {
  background-color: green;
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row: 2;
}

.wrapper div:nth-child(4) {
  background-color: lightblue;
  grid-column-start: 2;
  grid-row-end: 4;
}

.wrapper div:nth-child(5) {
  background-color: pink;
}

.wrapper div:nth-child(6) {
  background-color: lightgreen;
}
<div class="wrapper">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>