CSS网格:自动放置算法的工作原理



我正在浏览MDN文章中提供的关于网格自动流动的示例,以了解自动放置算法如何在CSS网格中工作。

以下是示例的定义(您可以在此处更改选择选项以更改网格自动流属性的值(:

function changeGridAutoFlow() {
var grid = document.getElementById("grid");
var direction = document.getElementById("direction");
var dense = document.getElementById("dense");
var gridAutoFlow = direction.value === "row" ? "row" : "column";
if (dense.checked) {
gridAutoFlow += " dense";
}
grid.style.gridAutoFlow = gridAutoFlow;
}
#grid {
height: 200px;
width: 200px;
display: grid;
grid-gap: 10px;
grid-template: repeat(4, 1fr) / repeat(2, 1fr);
grid-auto-flow: column;
/* or 'row', 'row dense', 'column dense' */
}
#item1 {
background-color: lime;
grid-row-start: 3;
}
#item2 {
background-color: yellow;
}
#item3 {
background-color: blue;
}
#item4 {
grid-column-start: 2;
background-color: red;
}
#item5 {
background-color: aqua;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="/static/build/styles/samples.37902ba3b7fe.css" rel="stylesheet" type="text/css" />
<title>grid-auto-flow - Setting_grid_auto-placement - code sample</title>
</head>
<body>
<div id="grid">
<div id="item1"></div>
<div id="item2"></div>
<div id="item3"></div>
<div id="item4"></div>
<div id="item5"></div>
</div>
<select id="direction" onchange="changeGridAutoFlow()">
<option value="column">column</option>
<option value="row">row</option>
</select>
<input id="dense" type="checkbox" onchange="changeGridAutoFlow()">
<label for="dense">dense</label>
</body>
</html>

现在,据我从MDN的另一篇文章中所了解,CSS网格按以下顺序放置项目:

  1. 显式放置:首先放置所有放置的项目(项目1和4(
  2. 隐式或自动放置:将所有其他项目按网格中定义的顺序值(如果有(放置。如果未定义顺序,请按它们在文档源中显示的顺序放置它们

现在我有两个关于它在上面的例子中如何工作的主要问题:

  1. 如果我们首先放置已定位的项目,那么在选项设置为的情况下,为什么不将项目4(红色(明确放置在第一行和第二列?为什么隐式放置的蓝色在第二列中被放在它之前?此外,当选项设置为时,这种行为似乎是正确的
  2. 为什么在值的情况下,自动放置的工作方式不同。在选项column的情况下,我们从填充列开始,那么为什么第一个自动放置的项目(项目2黄色(不能占据第1行第1列位置的空单元格(就像选项行的情况一样(

如果我们首先放置已定位的项,那么在选项设置为行的情况下,为什么不将已明确放置的项4(红色(放置在第一行和第二列?为什么隐式放置的蓝色在第二列中被放在它之前?此外,当选项设置为列时,这种行为似乎是正确的

为此,您需要参考规范和完整的放置算法:

  1. 生成匿名网格项
  2. 定位任何未自动定位的对象
  3. 处理锁定到给定行的项目
  4. 确定隐式网格中的列
  5. 定位其余网格项

诀窍是,你认为你的元素会被放在步骤(1(中,但没有。你的元素只有一个显式规则,另一个是自动的,所以它被视为自动定位的元素。

如果我们遵循规则,那么在步骤(1(中就没有要定位的元素。我们有一个元素要在步骤(2(中定位,即#item1,因为它被锁定到给定的行。然后所有其他元素都被放置在步骤(4(中,文档顺序将定义放置:

对于之前步骤尚未定位的每个网格项,在订单中修改文档订单

您没有使用order属性,因此文档顺序将作为参考。

值得注意的是,这同样适用于column流,但结果更直观,因为我们首先放置#item4(列锁定(,然后考虑到文档顺序,我们放置#item1(不是因为这个流有grid-row-start: 3;(


为什么在行和列值的情况下自动放置的工作方式不同。在选项列的情况下,我们从填充列开始,那么为什么第一个自动放置的项目(项目2黄色(不能占据第1行第1列位置的空单元格(就像在选项:行的情况下一样(

我认为上面的解释也涵盖了这一点。你需要遵循在两种情况下表现不同的算法:

为了便于理解,编写此算法时假设网格自动流已指定行。如果设置为column,则交换此算法中所有行和列、内联和块等的提及。

最新更新