开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第45天,点击查看活动详情
不同于以往使用定位浮动等布局模式,网格系统是一个专门解决布局问题的 CSS 模块。
基本术言
网格容器
设置了display:grid 的元素称为网格容器
<div class="container"> /* 网格容器 */
<div class="item item-1"> </div>
<div class="item item-2"> </div>
<div class="item item-3"> </div>
</div>
网格子项
网格容器的子代(非后代),顶级子代元素
<div class="container">
<div class="item"> </div> /* 网格子项,子代 */
<div class="item">
<p class="sub-item"> </p> /* 非网格子项,为后代元素 */
</div>
<div class="item"> </div>
</div>
网格线
构成网格的分割线
网格单元
两个相邻行和两个相邻列网格线之间的空间
网格轨道
可以将他们视为行或者列
网格区域
由任意个网格单元组成的区域
父级属性
display
定义一个块级网格容器
.container {
display: grid | inline-grid; /* 或者定义一个行内网格容器 */
}
grid-template-columns/rows
定义网格每一列列宽。定义网格每一行行高。
/* 定义列 */
.container {
grid-template-columns: 100px 100px 100px; /* 3列每列100px */
grid-template-columns: 33.33% 33.33% 33.33%; /* 3列每列33.33% */
grid-template-columns: 3fr 3fr 3fr; /* 3列平分宽度,fr是网格特有宽度 */
grid-template-columns: repeat(3, 3fr) /* 等于3fr 3fr 3fr,此函数可以进行重复性的工作 */
grid-template-columns: 1fr 30px 1fr; /* 中间30px,两边平分剩余宽度 */
grid-template-columns: repeat(auto-fill, 100px); /* 尽可能多的容纳元素,直到父元素宽度不够 */
grid-template-columns: 1fr 1fr minmax(100px, 200px); /* 第三列最小宽为100,最大宽为200 */
}
/* 定义行 */
.container {
grid-template-columns: 100px 100px 100px; /* 3行每行100px */
grid-template-columns: 33.33% 33.33% 33.33%; /* 3行每行33.33% */
grid-template-columns: 3fr 3fr 3fr; /* 3行平分宽度,fr是网格特有宽度 */
grid-template-columns: repeat(3, 3fr) /* 等于3fr 3fr 3fr,此函数可以进行重复性的工作 */
grid-template-columns: 1fr 30px 1fr; /* 中间30px,两边平分剩余高度 */
}
/* 定义网格线名称,若没定义,系统自动编号 */
.container {
grid-template-columns: [columnOne] 100px [columnTwo] 100px [columnThree] 100px [columnFour];
grid-template-rows: [rowOne] 100px [rowTwo] 100px [rowThree] 100px [rowFour];
}
px:像素空间%:按比例分配元素空间fr:按比例分配元素空间repeat:可以重复性工作minmax函数:能拉伸的最大值和缩小的最小值auto:由浏览器自己决定宽度
grid-template-areas
网格区域由一个一个网格组成,使用该属性能定义网格区域
.container {
grid-template-areas:
"<grid-area-name> | . | none | ..."
"...";
}
<grid-area-name>– 使用指定的网格区域的名称grid-area.– 一个句点表示一个空的网格单元none– 没有定义网格区域
定义网页布局案例:
-
首先定义一个 3 x 3 的网格:
.container { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; grid-template-areas: "a b c" /* 给网格区域命名 */ "d e f" "g h i"; } -
现在就有了 9 个网格单元,把这 9 个单元划分成下面的网格区域:
.container { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; grid-template-areas: "Header Header Header" "Nav Main Sidebar" "Nav Footer Footer"; }
grid-gap
grid-row-gap属性设置行与行的间隔
grid-column-gap属性设置列与列的间隔
grid-gap属性是grid-row-gap和grid-column-gap的合并写法
.container {
row-gap: 10px;
column-gap: 10px;
gap: 20px; /* row,column */
gap: 20px 20px; /* row,column */
}
grid-auto-flow
如果网格子项没有明确放在哪个位置,网格的自动放置算法会控制子项在网格中排放的位置。
.container {
grid-auto-flow: row | column | row dense | column dense;
}
row:告诉放置算法子项依次填充每一行,根据需要添加新行column:子项依次放置每一列,根据需要添加新列dense:如果前面的网格出现空余网格单元,则把后续较小的子项向前填充。案例
grid-auto-columns/rows
超出网格的子项的高度和宽度不受grid-template-columns/rows控制,需要用 grid-auto-rows / grid-auto-columns 才能控制。
.container {
display: grid;
grid-template-rows: repeat(2, 120px);
grid-template-columns: repeat(2, 100px);
gap: 20px;
grid-auto-rows: 50px;
grid-auto-columns: 50px;
}
现在我们有一个 2 x 2 的网格:
若现在有一个子项,其位置为 grid-row: 3 / 4,grid-columns: 3 / 4
这个时候网格容器就不得不开辟新的网格,并且新的网格宽度和高度都不确定会自适应:
item3是因为grid网格默认一行一行填满网格,因为item10位于网格外,2 x 2的网格不得不重新开辟成3 x 3的网格,会多出一行一列。item10的宽度跟随新开辟的列的宽度,高度自适应。
这时候使用 grid-auto-columns/rows 来控制溢出网格的列和行的宽高:
.container {
grid-auto-rows: 30px;
grid-auto-columns: 30px;
}
justify-items
子项在网格单元中的水平位置 。
.container {
justify-items: start | end | center | stretch;
}
stretch:默认值,拉正子项的宽度为网格单元的宽度(align-items 默认拉子项高度)start:元素位于网格单元开始处center:元素位于网格单元中心end:元素位于网格单元结束处
align-items
子项在网格单元中的垂直位置。
.container {
align-items: start | end | center | stretch | baseline;
}
stretch- 默认值,拉伸子项的高度填满其所在的网格单元start- 与网格单元的开始位置对其end- 与网格单元的结束位置对其center- 与网格单元的中心位置对其baseline-沿文本基线对齐
place-items(简写)
上面两个值的简写
.center {
display: grid;
place-items: center; /* align-items:center justify-items:center */
}
justify-content
网格单元在container容器里的水平位置
.container {
justify-content: start | end | center | stretch | space-around | space-between
| space-evenly;
}
start- 网格位于开始位置end- 网格位于结束位置center- 网格位于中间位置stretch- 网格子项没有指定大小时,拉伸填充整个网格容器space-around- 每一列子项都有空格space-between- 每两列子项之间有空格space-evenly- 每列网格的左右空格相等
align-content
网格单元在container容器里的垂直位置
.container {
align-content: start | end | center | stretch | space-around | space-between |
space-evenly;
}
stretch- 网格子项没有指定大小时,拉伸高度填充整个网格容器。
place-content(简写)
此属性是align-content + justify-content的简写
.center {
display: grid;
place-content: space-between; /* align-content:space-between justify-content:space-between */
}
grid-template/grid(简写)
非常不喜欢简写的方式,可读性差,不易修改,这里不再赘述。
子项属性
grid-column-start/end
通过参考线的位置确定子项在网格中的位置
.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;
}
number- 网格线编号,创建网格时若未给网格线命名,则浏览器将自动编号。name- 网格线名称,创建网格时给网格线的命名,有用户定义。span <number>- 跨越number个网格 。span <name>- 把网格跨越到网格名为name处。auto- 自适应放置。
例子:
.item {
grid-column-start: 1; /* 从第一条网格线开始 */
grid-column-end: span 2; /* 跨越2个网格单元 */
}
/* 上面的写法相当于 */
.item {
grid-column-start: 1; /* 从第一条网格线开始 */
grid-column-end: 3; /* 结束位置为第三条网格线 */
}
.item {
grid-column-start: columnTwo; /* 从名叫columnTwo的网格线开始 */
grid-column-end: span 2; /* 跨越两个网格单元 */
}
/* 上面的代码等价于 */
.item:first-child {
grid-column-start: 2; /* 从第2条网格线开始 */
grid-column-end: span columnFour; /* 跨越直到名称为columnFour的网格线处 */
}
grid-row-start/end(简写)
通过参考线的位置确定子项在网格中的位置,和上面一个属性的用法相似。
例子:
.item:first-child {
grid-row-start: 1; /* 从第一行网格线开始 */
grid-row-end: span 2; /* 跨越2行 */
}
/* 上面的代码等价于 */
.item:first-child {
grid-row-start: 1; /* 从第1行网格线开始 */
grid-row-end: 3; /* 到第3行网格线开始 */
}
.item {
grid-column-start: rowOne; /* 从名叫columnTwo的网格线开始 */
grid-column-end: span 3; /* 跨越两个网格单元 */
}
/* 上面的代码等价于 */
.item:first-child {
grid-column-start: 1; /* 从第2条网格线开始 */
grid-column-end: 4; /* 跨越直到名称为columnFour的网格线处 */
}
grid-column/row(简写)
grid-column 是 grid-column-start/end 的简写
grid-row 是 grid-column/row 的简写
.item {
grid-column: grid-column-start / grid-column-end;
grid-row: grid-row-start / grid-row-start;
}
例子:
/* 图一 */
.item:first-child {
grid-column: 1 / span 2;
grid-row: 1 / span 2;
}
/* 图二 */
.item:first-child {
grid-column: columnTwo / span 2;
grid-row: rowTwo / span 2;
}
grid-area
可以直接分配该子项到已命名的网格区域,可以视为 4 个属性的简写(grid-row-start + grid-column-start + grid-row-end + grid-column-end)
.item {
grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
}
name- 网格区域名称- 剩下四个属性:数字或行名
例子:
.container {
grid-template-areas:
"header header header"
"sidebar main rightbar"
"footer footer footer";
}
.item1 {
/* 数字为1的网格 */
grid-area: header;
}
.container {
grid-template-areas:
"header header header"
"sidebar main rightbar"
"footer footer footer";
}
.item1 {
/* 数字为1的网格 */
grid-area: 2 / 2 / span 1 / span 2;
}
justify-self
适用于单个子项在网格单元内的水平排列。
.item {
justify-self: start | end | center | stretch;
}
stretch- 默认值,没有默认宽度时拉伸填满整个单元格
align-self
适用于单个子项在网格单元内的垂直排列。
.item {
align-self: start | end | center | stretch;
}
stretch- 默认值,没有默认高度时拉伸填满整个单元格
place-self(简写)
该属性是 <align-self> / <justify-self> 的简写
.item-a {
place-self: center; /* align-self:center justify-self:center */
}
特殊单位
fr
本质是指使用剩余空间,占据一定比例的空间。
.container {
grid-template-columns: 1fr 3fr; /* 等价于 25% 75% */
}
也可以和其他值结合起来使用:
.container {
grid-template-columns: 50px min-content 1fr;
}
minmax
他设置了宽度能到达的最大值和最小值
.container {
grid-template-columns: minmax(100px, 1fr) 3fr;
}
repeat
可以省略一些重复性的功能
.container {
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr
/* 上面的写法等价于 */
grid-template-columns: repeat(6, 1fr)
/* 可以和minmax函数以及其他关键字结合使用 */
grid-template-columns: repeat(6, minmax(10px, 1fr))
}
auto-fill
在一行中尽可能加入有宽度的列来填充空白空间,两者区别
.grid {
display: grid;
gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));
}
.grid > div {
height: 100px;
background: red;
}
auto-fit
在一行中尽可能拉伸列的宽度填充空白空间,两者区别
.grid2 {
display: grid;
gap: 10px;
grid-template-columns: repeat(auto-fit, minmax(50px, 1fr));
}
.grid2 > div {
height: 100px;
background-color: antiquewhite;
}
非媒体查询实现响应网格
它包含了所有 CSS Grid 中最著名的代码片段,也是有史以来最伟大的 CSS 技巧之一
grid-template-columns: repeat(auto-fill, minmax(min(10rem, 100%), 1fr));