Grid 布局
网格布局
网格布局(Grid Layout)是一个基于网格的二维布局系统,而 flexbox 布局则是一维的。
.grid-container {
display: grid | inline-grid | subgrid;
}
- grid - 生成一个块级网格
- inline-grid - 生成一个内联网格
- subgrid - 生成一个子网格,可以继承父级网格容器行/列的大小
Grid 布局在线 demo 戳这里或者 css-grid-playground 👈👈👈
在网格容器(Grid Container) 上使用
float、clear、vertical-align会失效。
container 属性
Grid 容器上有下列属性:
| 属性 | 描述 |
|---|---|
| grid-template-columns/rows | 定义网格的列宽和行高 |
| grid-template-areas | 通过引用 grid-area 属性指定的网格区域(Grid Area)名称来定义网格模板 |
| grid-template | 以上三者的复合属性 |
| grid-gap | grid-row-gap 和 grid-column-gap 的复合属性,定义网格线(grid lines)的大小 |
| justify-items | 沿着 行轴线(row axis) 对齐 网格项(grid items) 内的内容 |
| align-items | 沿着 列轴线(column axis) 对齐 网格项(grid items) 内的内容 |
| justify-content | 设置网格容器内的网格的对齐方式。 此属性沿着 行轴线(row axis) 对齐网格 |
| align-content | 设置网格容器内的网格的对齐方式。 此属性沿着 列轴线(column axis) 对齐网格 |
| grid-auto-columns/rows | 指定任何自动生成的网格轨道(grid tracks)的大小 |
| grid-auto-flow | 控制自动布局算法如何工作 |
| grid | 复合属性 |
grid-template
grid-template 属于 grid-template-rows、grid-template-columns 和 grid-template-areas 的复合属性,可以使用空格分隔的值列表,用来定义网格的列和行以及区域。这些值表示网格轨道(Grid Track)大小,它们之间的空格表示网格线。
grid-template-columns
两条相邻网格线之间的空间,你可以把它们想象成网格的列高或行宽:
.item {
/* <track-size>: 可以是长度值,百分比,或者等份网格容器中可用空间(使用 fr 单位) */
grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}
.grid-container {
/* 列宽 */
grid-template-columns: 40px 50px auto 50px 40px;
/* 行高 */
grid-template-rows: 25% 100px auto;
}
你还可以对网线进行命名,方便引用:
/* 指定网格布局为 3行 x 3列,因此有 4 根垂直网格线和 4 根水平网格线。方括号里面依次是这八根线的名字 */
.container {
display: grid;
grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4];
}
repeat()
如果你的定义包含多个重复值,则可以使用 repeat() 表示法来简化定义:
.item {
grid-template-columns: repeat(3, 20px) 5%;
/* 等同于 */
grid-template-columns: 20px 20px 20px 5%;
}
fr 可用空间
fr 单元允许你用等分网格容器剩余可用空间来设置网格轨道的大小。剩余可用空间是除去所有非灵活网格项之后计算得到的:
/* 可用空间总量除去 50px,再均分为三等分 */
.item {
grid-template-columns: 1fr 50px 1fr 1fr;
}
minmax()
minmax() 函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值:
/* minmax(100px, 1fr) 表示列宽不小于 100px,不大于 1fr */
grid-template-columns: 1fr 1fr minmax(100px, 1fr);
grid-template-areas
通过引用 grid-area 属性指定的网格区域(Grid Area)名称来定义网格模板。一个点号(.)代表一个空的网格单元:
/* 创建一个 4 列 3 行的网格。 */
/* 整个顶行将由 header 区域组成。 */
/* 中间一排将由两个 main 区域、一个空网格单元和一个 sidebar 区域组成。 */
/* 整个最后一行将由 footer 区域组成。 */
.item-a {
grid-area: header;
}
.item-b {
grid-area: main;
}
.item-c {
grid-area: sidebar;
}
.item-d {
grid-area: footer;
}
.grid-container {
grid-template-columns: 50px 50px 50px 50px;
grid-template-rows: auto;
grid-template-areas:
"header header header header"
"main main . sidebar"
"footer footer footer footer";
}
grid-gap
grid-row-gap 和 grid-column-gap 一样,指定网格线(grid lines)的大小,即设置列/行之间的间距:
.item {
/* grid-gap 为复合属性 */
/* 如果 grid-row-gap 没有定义,那么就会被设置为等同于 grid-column-gap 的值 */
grid-gap: <grid-row-gap> <grid-column-gap>;
grid-column-gap: <line-size>;
grid-row-gap: <line-size>;
}
grid-auto-columns
和 grid-auto-rows 指定任何自动生成的网格轨道(grid tracks)的大小,又称隐式网格轨道。在你明确定位的行或列(通过 grid-template-rows / grid-template-columns)超出定义的网格范围时,隐式网格轨道将被创建:
/* 第五和第六列网格线未被定义 */
.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}
.grid-container {
grid-template-columns: 60px 60px;
grid-template-rows: 90px 90px
}
/* 指定这些隐式轨道的大小 */
.grid-container {
grid-auto-columns: 60px;
}
grid-auto-flow
如果存在一些没有明确放置在网格上的网格项(grid items),自动放置算法会自动放置这些网格项。该属性控制自动布局算法如何工作:
.item {
grid-auto-flow: row | column | row dense | column dense
}
网格项对齐
justify-items
沿着 行轴线(row axis) 对齐 网格项(grid items) 内的内容:
.item {
justify-items: start | end | center | stretch;
}
.item {
justify-items: start;
}
align-items
沿着 列轴线(column axis) 对齐 网格项(grid items) 内的内容:
.item {
align-items: start | end | center | stretch;
}
.item {
align-items: start;
}
place-items
属于 align-items 和 justify-items 的复合属性:
.item {
/* 如果省略第二个值,则浏览器认为与第一个值相等 */
place-items: <align-items> <justify-items>
/* 例如 */
place-items: center;
}
网格容器对齐
justify-content
设置网格容器内的网格的对齐方式。此属性沿着 行轴线(row axis) 对齐网格:
/* 针对网格合计大小可能小于其 网格容器(grid container) 大小 */
.item {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
.item {
justify-content: start;
}
align-content
设置网格容器内的网格的对齐方式。 此属性沿着 列轴线(column axis) 对齐网格
/* 针对网格合计大小可能小于其 网格容器(grid container) 大小 */
.item {
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
.item {
align-content: start;
}
place-content
属于 align-content 和 justify-content 的复合属性:
.item {
/* 同样如果省略第二个值,则浏览器认为与第一个值相等 */
place-content: <align-content> <justify-content>
/* 例如 */
place-content: center;
}
grid
属于 grid-template-rows、grid-template-columns、grid-template-areas、grid-auto-rows、grid-auto-columns 和 grid-auto-flow 的复合属性:
.container {
grid: 100px 300px / 3fr 1fr;
}
/* 等价于 */
.container {
grid-template-rows: 100px 300px;
grid-template-columns: 3fr 1fr;
}
/* 此用例的grid属性相当于grid-template */
.grid-container {
grid: [row1-start] "header header header" 1fr [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
/* 等价于 */
.grid-container {
grid-template-areas:
"header header header"
"footer footer footer";
grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
}
item 属性
注意:
float,display: inline-block,display: table-cell,vertical-align 和 column-*属性对网格项无效。
grid-column-start / grid-row-start
通过引用特定网格线(grid lines) 来确定 网格项(grid item) 在网格内的位置。 grid-column-start / grid-row-start 是网格项开始的网格线,grid-column-end / grid-row-end 是网格项结束的网格线:
- <line> - 可以是一个数字引用一个编号的网格线,或者一个名字来引用一个命名的网格线
- span <number> - 该网格项将跨越所提供的网格轨道数量
- span <name> - 该网格项将跨越到它与提供的名称位置
- auto - 表示自动放置,自动跨度,默认会扩展一个网格轨道的宽度或者高度
.item {
grid-column-start: <number> | <name> | span <number> | span <name> | auto;
grid-column-end: <number> | <name> | span <number> | span <name> | auto;
grid-row-start: <number> | <name> | span <number> | span <name> | auto;
grid-row-end: <number> | <name> | span <number> | span <name> | auto;
}
.item-a {
grid-column-start: 2;
grid-column-end: five;
grid-row-start: row1-start;
grid-row-end: 3;
}
/* span 2 表示跨越两个网格,即 grid-row-end 相当于 4 */
.item-b {
grid-column-start: 1;
grid-column-end: span col4-start;
grid-row-start: 2;
grid-row-end: span 2;
}
若
grid-column-end/grid-row-end没有定义, 则默认跨越一个网格 👈
grid-column / grid-row
分别为 grid-column-start / grid-column-end 和 grid-row-start / grid-row-end 的简写形式:
.item {
grid-column: <start-line> / <end-line> | <start-line> / span <value>;
grid-row: <start-line> / <end-line> | <start-line> / span <value>;
}
.item-c {
grid-column: 3 / span 2;
grid-row: third-line / 4;
}
grid-area
grid-area 为网格项提供一个名称,以便可以 被使用网格容器 grid-template-areas 属性创建的模板进行引用,上面已经有栗子了。不过它还有另外一个用法,这个属性可以用作 grid-row-start / grid-column-start / grid-row-end / grid-column-end 的简写:
.item {
grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
}
.item-d {
grid-area: 1 / col4-start / last-line / 6;
}
justify-self
沿着 inline(行)轴线对齐网格项( 相反的属性是 align-self ,沿着 block(列)轴线对齐)。此值适用于单个网格项内的内容:
.item {
justify-self: start | end | center | stretch;
}
.item {
justify-self: start;
}
align-self
沿着 block(列)轴线对齐网格项(grid items)( 相反的属性是 justify-self ,沿着 inline(行)轴线对齐)。此值适用于单个网格项内的内容:
.item {
align-self: start | end | center | stretch;
}
.item {
align-self: start;
}
place-self
属于 align-self 和 justify-self 的复合属性:
.item {
/* 同样如果省略第二个值,则浏览器认为与第一个值相等 */
place-self: <align-self> <justify-self>
/* 例如 */
place-self: center;
}
参考链接
- A Complete Guide to Grid By Chris House
- CSS Grid VS Flexbox: A Practical Comparison By Danny Markov
- CSS Grid 布局这样玩 By 大漠
- CSS Grid 布局完全指南 By 渔人码头