您需要了解放置算法才能理解此行为。从规格您可以找到完整的算法以及如何识别when每个项目都会被处理,这是理解两种情况之间差异的关键。
算法的主要步骤是:
-
生成匿名网格项
-
放置任何未自动定位的东西。
-
处理锁定到给定行的项目。
-
确定隐式网格中的列。
-
放置剩余的网格项。
让我们从最后一个示例开始,您在其中明确定义了grid-colum
and grid-row
对于第一个项目,使其成为不自动定位元素,因此我们将其放置在步骤 (1) 中。
然后我们将进入步骤(4)来放置剩余的项目
自动放置光标定义网格中的当前“插入点”,指定为一对行和列网格线。最初的自动放置光标设置为隐式网格中最开始的行线和列线。
因此,我们的光标位于顶部/左侧单元格,item2 将放置在那里,我们只需按照树顺序放置所有其他元素:
对于前面步骤中尚未定位的每个网格项,按顺序修改的文档顺序:
当然,没有任何项目会与已放置的 item1 重叠,并且我们会按照算法不断增加每个项目的光标。
现在让我们考虑第一个tricky唯一的区别是您没有指定的情况grid-row
这将不再使你的元素成为不自动定位一是因为您只定义了grid-column
因此该行将被自动定义,并且该项目现在将落入步骤(4),如果仔细检查步骤(4),您会发现两个子步骤:
如果该项目有明确的列位置:
如果该项目在两个轴上都有自动网格位置:
item1 将考虑第一个,将被放置在第二列中,并将增加光标!。光标的增量使得第二个元素放置在其后。
在您的第二个示例中,item1 将不会使用光标,因为它在步骤 (1) 中被考虑,因此 item2 将是第一个使用光标的项目,这与第一个示例中的 item1 将是第一个使用它的项目不同。
值得注意的是,在步骤(4)中我们有两种算法。 “稀疏”行为(默认行为),我们从不重置光标,并且总是递增它,从而产生间隙。 “密集”算法在每一步重置光标以填充所有单元格。要激活“密集”算法,您需要考虑grid-auto-flow
.container {
display: grid;
margin: 40px;
grid-gap: 20px;
text-align: center;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(4, 1fr);
grid-auto-flow: dense;
}
.container div {
background: #ff8000;
}
.container .item1 {
grid-column: 2/4;
}
<div class="container">
<div class="item1">1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
</div>
dense
如果指定,自动放置算法将使用“密集”打包算法,如果稍后出现较小的项目,该算法会尝试先填充网格中的空洞。这可能会导致项目看起来无序,因为这样做会填补较大项目留下的漏洞。
If omitted, a “sparse” algorithm is used, where the placement algorithm only ever moves “forward” in the grid when placing items, never backtracking to fill holes. This ensures that all of the auto-placed items appear “in order”, even if this leaves holes that could have been filled by later item ref
与使用相同算法解释的另一个非直观行为相关的问题:CSS 网格:自动放置算法的工作原理