CSS Grid布局:理解CSS Grid中自动排列的算法
在这个系列教程中的《列和间距》一文中了解到了在CSS Grid布局中如何实现流体网格列和列间距。也了解到了没有必要指定网格项目具体的值就可以实现网格项目的排列位置。如果显式声明网格属性,网格项目根据自动排列算法,会使网格排列变得更糟糕。
在这篇文章中我们将看看这个算法是如何影响网格项目的位置排列。
配置
如果你的浏览器不支持CSS Grid,那么你可以先阅读系列中第一篇文章《快速入门》。
开始制作一个网格
这个案例是制作一个网格。它需要一个容器,并且使用display:grid;将其声明为一个网格容器;另外这个容器有18个子元素。希望这个网格是具有五个列,每个列的宽度相同,并且具有相同数量的行,网格之间的间距为2px。
到目为止,看到的网格很好,它有18个网格子,一行一行的向下排列,看上去就像是使用float得到的排列效果。
注:看到的效果是从左到右排列,如果你想得到一个从右到左的排列,可以使用direction:rtl。
稍作调整
上面的效果看上去整洁漂亮。但如果我们改变第七个网格.item-7,让这个网格变得更大,占据两行两列,那么网格会变成什么样:
这时你看到的网格像下面这样:
不是太坏。.item-7空间变得更大了,所以.item-8和.item-9向后排列,其中.item-8占据了一开始的.item-9,而.item-9占据了一开始的.item-10。而.item-10自动换行,排在新的一行第一列位置处。同时,其他的网格项目,也按这样的堆叠方式向后排列。
但是,如果.item-9也要像.item-7一样,占据的空间变得更大,这里看到的效果如下:
现在变得有意思了。.item-9不再适合放在最后一列了被推到新的一行。你可能会想.item-10会自动排在.item-6下面,但事实上并不是这样。如果你还记得,事实上.item-10会寻找一个新的行(也就是分流术),就不会这么认为了。这其实就是一个概念,理解了这个概念就搞明白了。
grid-auto-flow
grid-auto-flow默认值是row,如果需要我们可以将它的值设置为column,这个时候完全改变了网格的展示方式。网格项目会按列的方式排列,.item-18没有找到可放置的空间,因为我们的网格声明的是一个五行五列的网格。
网格项目的排列顺序看起来是类似的,你应该也注意到了,.item-7排列在.item-6下面,同时占据两行两列的空间。.item-8和.item-9自动排列到.item-7后面,但.item-10之后的网格项目自动流入到下一列,如此一来,就看到了上面的效果,.item-18没有位置放了。
dense带来的改变
可以给grid-auto-flow属性添加另外一个关键词dense,它可能是我至今为止最喜欢的一个CSS关键词。其对应的默认值是sparse。实际上我们可以这样做:
grid-auto-flow: row dense;
注:实际上不需要使用row,这是隐性的(默认的值),但为了突出语法是如何工作的,在显式声明。
现在看起来很好。.item-9发现没有空间自动换到新的一行,而.item-10检查前面的空间,自动补上。
这还得感谢网格自动排列算法,给我们一个更有效的网格。这也意味着,它不能友好的反映文档流顺序。这一点对于一些用户而言并不总是有用的。
补充一点,基于上面的示例,将grid-auto-flow设置为:
grid-auto-flow: column dense;
看到的效果如下:
总结
简单总结一下:
-
如果没有明确指定网格项目位置,网格会按自动排列算法,将它最大化利用可用空间
-
如果在当前行没有可用位置,网格会自动搜索下一行,这样会造成一定的差距,浪费可用空间
-
可以把grid-auto-flow的row值改变auto,可以切换搜索顺序
-
grid-auto-flow还可以接受另一个关键词。默认情况下,其值是sparse,但我们可以将其显式的设置为dense,让网格项目试图自动填补所有可用的空白空间