网格

你有一个页面,顶部有标题栏,左侧有侧边栏,中间有主内容区,底部有页脚。你可以嵌套多个容器,并将每个容器推到适当的位置,这样做是可行的,直到你需要改变布局的那一天。CSS 网格正是为了解决这种问题而构建的:同时用行和列来布局页面。一旦你能将布局描述为一组轨道,大部分关于包装器和浮动的调整就消失了。
网格容器
将任何元素设置为 display: grid 可以将其变成网格。该元素成为 网格容器,它的直接子元素成为吸附到你定义的网格中的项目。仅仅设置 display: grid 不会做太多事情,所以你还需要告诉它你想要多少列和行,以及每一个应该有多大。
你用 grid-template-columns 描述列,用 grid-template-rows 描述行。列表中的每个值都是一个轨道,一个轨道是单个列或行:
.layout {
display: grid;
grid-template-columns: 200px 1fr; /* 两列:一个固定的,然后是剩余部分 */
grid-template-rows: 80px 400px; /* 两行:一个短的,然后是一个高的 */
}display: grid,它就变成了网格容器,它的直接子元素作为项目位于其中。然后你用 grid-template-columns 和 grid-template-rows 说明你想要多少列和行,每个轨道一个值。没有定义那些轨道,什么都不会排列,所以这总是你的第一步。 灵活轨道
固定像素列还可以,但大多数布局需要列平均共享空间并随屏幕增长。这正是 fr 单位 的用途。一个 fr 意味着一份剩余空间,所以三列各 1fr 各占容器的三分之一:
.gallery {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 三个相等的列 */
}输入三次 1fr 会很乏味,所以 repeat() 为你写好。gap 设置轨道之间的空间,所以你不用为每个项目都设置边距:
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 相同的三个相等列 */
gap: 16px; /* 行列之间的空间 */
}fr 是一份剩余空间,所以 1fr 1fr 1fr 给你三个相等的列。使用 repeat(3, 1fr) 这样你就不用一遍遍输入相同的值,用 gap 表示轨道之间的空间。一旦我理解了 fr,我就停止使用永远加不起来的百分比了。 放置项目
默认情况下,每个项目按顺序放入下一个空闲单元,每个单元一个。当你想让一个项目占用多于一个单元时,你用 grid-column 和 grid-row 说明。轨道之间的线从 1 开始编号,所以 grid-column: 1 / 3 表示"从线 1 开始,在线 3 结束",覆盖两列:
.featured {
grid-column: 1 / 3; /* 从列线 1 到线 3,两列宽 */
}如果你不想数线,span 说明从项目着陆处开始覆盖多少个单元:
.featured {
grid-column: span 2; /* 覆盖两列,从这个项目所在的任何地方开始 */
}grid-column 或 grid-row 让一个跨越单元。线号从 1 开始,所以 grid-column: 1 / 3 覆盖两列,或者如果你不想数,使用 span 2。在你命名任何单个区域之前,这足以构建大多数布局。 不使用媒体查询的响应式网格
一行卡片应该在宽屏上显示三个并排,在平板上显示两个,在手机上显示一个。你可以仅用网格做到这一点,不需要写任何断点。技巧是一行:
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
}从里到外读。minmax(200px, 1fr) 意味着每列至少 200px 最多一份空间。auto-fit 然后将尽可能多的这些列放入容器有房间的地方。宽屏幕,更多列放进去;窄屏幕,较少列,卡片自动重流。
repeat(auto-fit, minmax(200px, 1fr)) 让卡片自动重流,不需要断点。每列至少 200px 最多一份空间,auto-fit 尽可能多地装入。改变 200px,你改变有多少卡片并排。 
