Grid布局是目前唯一的二维 CSS 布局,对比于作用于一维的Flex布局,Grid更适合构建网格系统,比如很常见的自适应卡片布局

现在有一个div容器如下

.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 10px;
  padding: 10px;
  box-sizing: border-box;
}

其中的grid-template-columns是一种响应式写法,其中的卡片最小宽度为250px,每一行会根据宽度放入足够多的卡片,为卡片添加一些样式后,页面显示如下(一行显示五个卡片的原因和显示器的尺寸有关)

当改变窗口宽度时,卡片会自动进行排列

这里可以看到gird布局中默认的排列方式是按照行来排列,gird会优先按照行的顺序来排列元素,但是我们也可以手动指定排列方式,只需要修改grid-auto-flowcolumn即可

需要注意的是因为本例列数是响应式的,如果你想要按照列排列,就需要指定行数,否则grid无法知道你需要多少行。或者可以取消列的响应式

这里我将 row 设置为四行,同时grid-auto-flow: column,就可以看到如下效果

到这为止,好像grid-auto-flowrowcolumn属性已经足够我们使用了,但其实还有另外一个属性dense

我们假设有这样的场景,每个卡片的大小不是固定的,有些卡片占用了更多的的空间,比如这样

这样看上去没什么,但假如我们改变窗口的宽度,就会出现这样的情况

第10和第11个卡片之间出现了空白,这是设置grid-auto-flow: row的情况,我们再来看看按列排列

同样的,第20和第21个卡片之间也出现了空白

产生这种现象的原因是,无论是按照行排列或者是按照列排列,gird都会在空间不足时候另起一行/列来容纳对应的元素,简单的说,grid-auto-flowcolumnrow属性保证了在布局变化时元素原本的顺序,这对需要保证顺序的场景是很有必要的,但有些时候,我们不需要去考虑元素的顺序,我们只想尽可能填充满所有的空间,这时候就可以使用dense属性

dense在这里的意思是 密集的;稠密的

设置为dense后,gird会将其他符合大小的元素填充到空白区域

可以明显的看到,原本的第12和13号卡片填充到了上方

总结

  • Grid布局的默认排序为row排序
  • 可以手动指定为column
  • 无论是row还是column都可能会造成空间的浪费
  • 如果需要最大化的可用空间,同时不需要考虑元素的顺序,dense是更好的选择