Grid布局的那些事儿!
网格布局 Grid Layout
网格布局是一种二维的布局模式。可用于页面主要的区域布局或小型组件。
术语
Grid
通过设置dispaly: grid;
或者display: inline-grid;
把一个容器变成一个Grid容器,那么它的直系子元素则是Grid元素。
网格线 Grid lines
使用Grid布局在显式网格中定义轨道的同时会创建网格线。
css
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 60px);
}
html
<div class="wrapper">
<div class="item item1"></div>
<div class="item item2"></div>
<div class="item item3"></div>
<div class="item item4"></div>
<div class="item item5"></div>
<div class="item item6"></div>
<div class="item item7"></div>
<div class="item item8"></div>
<div class="item item9"></div>
</div>
上面的例子三行三列的网格,它有4条行线(row-line)和和4条列线(col-line)。
在从左到右的语言中,线编号如下图所示(线编号遵循文档的写入模式)。
网格轨道 Grid tracks
两条网格线之间的空间叫做网格轨道,同样是上面的例子,会有三个行轨道和三个列轨道。如下图所示:
网格单元格 Grid cell
两条行网格线与两条列网络线之间的空间叫做单元格,这与表格里面的单元格定义是一致的。
网格单元格是网格布局中的最小单元。
网格区域 Grid areas
网格区域指的是由一个或多个单元格组成的 矩形区域。
网格间隙 Gutters
网格间隙指两个单元格之间的间距。
网格轴 Grid Axis
网格中有两个轴,横轴(行轴)和纵轴(列轴)。沿着这些轴可以对项目进行行对齐和列对齐。
这些轴的物理方向会根据文档的写入模式writing-mode
而改变。
属性
grid-template-columns
grid-template-columns
可以用来定义列网格线的名称和网格轨道的尺寸大小。
语法:
css
grid-template-columns: 100px 1fr;
grid-template-columns: [linename] 100px;
grid-template-columns: [linename1] 100px [linename2 linename3];
grid-template-columns: minmax(100px, 1fr);
grid-template-columns: fit-content(40%);
grid-template-columns: repeat(3, 200px);
grid-template-columns: 200px repeat(auto-fill, 100px) 300px;
grid-template-columns: minmax(100px, max-content)
repeat(auto-fill, 200px) 20%;
grid-template-columns: [linename1] 100px [linename2]
repeat(auto-fit, [linename3 linename4] 300px)
100px;
grid-template-columns: [linename1 linename2] 100px
repeat(auto-fit, [linename1] 300px) [linename3];
[linename]
:表示该网格线的自定义名称;repeat()
:表示重复定义多个网格轨道;接受2个参数,第一个参数可以是正整数、auto-fill
(自动计算剩余的空间可分布多少个轨道,如果容器的宽度足够大,会生成空的轨道项用于填充)或者auto-fit
(与auto-fill相似,但是不会生成空的轨道项);第二个参数则是尺寸值。minmax(min, max)
:定义最小尺寸与最大尺寸。如果max值小于min值,该轨道的尺寸则会被视为min值max-content
:是一个用来表示以网格项的最大的内容来占据网格轨道的关键字(只能当max参数传入)。min-content
:是一个用来表示以网格项的最大的最小内容来占据网格轨道的关键字(只能当max参数传入)。
auto-fill
auto-fit
css
.wrapper {
display: grid;
grid-template-columns: [myFirstLine] 100px [mySecondLine] 150px [myThirdLine] 200px [myLastLine];
}
.item8 {
grid-column-start: myFirstLine;
grid-column-end: myThirdLine;
background: blue;
}
html
<div class="wrapper">
<div class="item item1">item 1</div>
<div class="item item2">item 2</div>
<div class="item item3">item 3</div>
<div class="item item4">item 4</div>
<div class="item item5">item 5</div>
<div class="item item6">item 6</div>
<div class="item item7">item 7</div>
<div class="item item8">item 8</div>
<div class="item item9">item 9</div>
</div>
grid-template-rows
grid-template-rows
可以用来定义行网格线的名称和网格轨道的尺寸大小。(设置方式与grid-template-columns
一样)
grid-template-areas
grid-template-areas
这个属性非常有意思,可以让我们很直观地进行布局。
css
.wrapper {
display: grid;
grid-template-columns: repeat(9, 50px);
grid-auto-rows: 100px;
grid-template-areas:
"hd hd hd hd hd hd hd hd hd"
"sd sd sd main main main main main main"
"sd sd sd ft ft ft ft ft ft"
;
}
.header {
grid-area: hd;
background-color: lightblue;
}
.side {
grid-area: sd;
background-color: indianred;
}
.main {
grid-area: main;
background-color: gray;
}
.footer {
grid-area: ft;
background-color: black;
}
html
<div class="wrapper">
<div class="item header">header</div>
<div class="item side">side</div>
<div class="item main">main</div>
<div class="item footer">footer</div>
</div>
也可以通过点(.)的方式来占位留空。还是上面的例子,其他内容不变。
css
.wrapper {
grid-template-areas:
"hd hd hd hd hd hd hd hd hd"
"sd sd sd main main main main main main"
". . . ft ft ft ft ft ft"
;
}
grid-template
grid-template
是grid-template-areas
、grid-template-rows
与grid-template-columns
的简写形式。
语法:
css
/* 为 grid-template-rows / grid-template-columns */
grid-template: 100px 1fr / 50px 1fr;
grid-template: auto 1fr / auto 1fr auto;
grid-template: [linename1] 100px / [linename2] 30% [linename3] 70%;
grid-template: fit-content(100px) / fit-content(40%);
/* 为 grid-template-areas grid-template-rows / grid-template-column */
grid-template:
"a a a"
"b b b"
;
grid-template:
"a a a" 20%
"b b b" auto
;
grid-template:
[linename1] "a a a" [linename2]
[linename3] "b b b" 1fr [linename4] / auto 1fr auto
;
css
.wrapper {
display: grid;
grid-template:
"hd hd" 100px
"sd main" 1fr
"sd ft" 100px / 80px 1fr;
;
width: 300px;
height: 500px;
}
html
<div class="wrapper">
<div class="item header">header</div>
<div class="item side">side</div>
<div class="item main">main</div>
<div class="item footer">footer</div>
</div>
grid-auto-columns
grid-auto-columns
隐式地定义了列轨道的尺寸。
语法:
css
/* Keyword values */
grid-auto-columns: min-content;
grid-auto-columns: max-content;
grid-auto-columns: auto;
/* <length> values */
grid-auto-columns: 100px;
grid-auto-columns: 20cm;
grid-auto-columns: 50vmax;
/* <percentage> values */
grid-auto-columns: 10%;
grid-auto-columns: 33.3%;
/* <flex> values */
grid-auto-columns: 0.5fr;
grid-auto-columns: 3fr;
/* minmax() values */
grid-auto-columns: minmax(100px, auto);
grid-auto-columns: minmax(max-content, 2fr);
grid-auto-columns: minmax(20%, 80vmax);
/* fit-content() values */
grid-auto-columns: fit-content(400px);
grid-auto-columns: fit-content(5cm);
grid-auto-columns: fit-content(20%);
/* multiple track-size values */
grid-auto-columns: min-content max-content auto;
grid-auto-columns: 100px 150px 390px;
grid-auto-columns: 10% 33.3%;
grid-auto-columns: 0.5fr 3fr 1fr;
grid-auto-columns: minmax(100px, auto) minmax(max-content, 2fr) minmax(20%, 80vmax);
grid-auto-columns: 100px minmax(100px, auto) 10% 0.5fr fit-content(400px);
grid-auto-rows
grid-auto-rows
隐式地定义了行轨道的尺寸。
css
.wrapper {
display: grid;
grid-template-areas: "a a a";
grid-auto-columns: 100px 50px 200px;
grid-auto-rows: 60px 100px 50px;
}
html
<div class="wrapper">
<div class="item item1">这里是Item 1</div>
<div class="item item2">item 2</div>
<div class="item item3">item 3</div>
<div class="item item4">item 4</div>
<div class="item item5">item 5</div>
<div class="item item6">item 6</div>
<div class="item item7">item 7</div>
<div class="item item8">item 8</div>
<div class="item item9">item 9</div>
</div>
grid-auto-flow
grid-auto-flow
指定网格元素则如何排列。
该属性有两种形式:
- 单个关键字:
row
、column
或dense
中的一种; - 两个关键字:
row dense
或column dense
。
row
关键字指定元素逐行填充;
column
关键字指定元素逐列填充;
dense
关键字指定元素使用“紧凑”的堆积算法,如果后面出现了稍微小的元素,则会试图填充网格中前面的空白部分。这样做可能会导致元素出现的次序被打乱。
grid-column-gap
指定两个相邻的列单元格之间的间隙。
grid-column-gap: 10px;
grid-row-gap
指定两个相邻的列单元格之间的间隙。
grid-row-gap: 2em;
grid-gap
grid-row-gap
与grid-column-gap
的缩写形式。
grid-gap: 2vmin 20%;
grid
grid
是一个缩写形式。可以用以设置以下属性:
grid-template-rows
、grid-template-columns
和grid-template-areas
;grid-auto-rows
、grid-auto-columns
和grid-auto-flow
。
注意:grid
只能定义其中一种。
定位
grid-column-start
: 定义grid元素从哪条列线开始排列grid-column-end
: 定义grid元素到哪条列线结束grid-row-start
: 定义grid元素从哪条行线开始排列grid-row-end
: 定义grid元素到哪条行线结束grid-column
: grid-column-start / grid-column-end 的简写grid-row
: grid-row-start / grid-row-end 的简写grid-area
: grid-row-start / grid-column-start / grid-row-end / grid-column-end 的简写
css
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px 1fr 150px;
}
.item1 {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
}
.item2 {
grid-column-start: 4;
grid-row: 1 / 3;
}
.item3 {
grid-column-start: 5;
grid-column-end: span 2;
grid-row: 2 / span 2;
}
.item6 {
grid-area: 3 / 2 / 4 / span 3;
}
html
<div class="wrapper">
<div class="item item1">这里是Item 1</div>
<div class="item item2">item 2</div>
<div class="item item3">item 3</div>
<div class="item item4">item 4</div>
<div class="item item5">item 5</div>
<div class="item item6">item 6</div>
<div class="item item7">item 7</div>
<div class="item item8">item 8</div>
<div class="item item9">item 9</div>
</div>
对齐属性
justify-items、justify-self
justify-items
批量定义元素在列线上的对齐方式,justify-self
则是定义指定的元素在列线上的对齐方式。
可接受的值如下:
- auto
- normal
- start
- end
- center
- stretch
- baseline
- first baseline
- last baseline
css
.wrapper {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 100px 100px;
justify-items: stretch; /* 拉伸对齐 */
}
.item2 {
justify-self: end;
}
.item3 {
justify-self: center;
}
.item4 {
justify-self: start;
}
html
<div class="wrapper">
<div class="item item1">item 1</div>
<div class="item item2">item 2</div>
<div class="item item3">item 3 item 3</div>
<div class="item item4">item 4</div>
</div>
align-items、align-self
align-items
批量定义元素在行线上的对齐方式,align-self
则是定义指定的元素在行线上的对齐方式。
css
.wrapper {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 100px 100px;
align-items: stretch;
}
.item2 {
align-self: end;
}
.item3 {
align-self: center;
}
.item4 {
align-self: start;
}
justify-content
定义所有元素整体在列轴上的对齐方式(类似flex里面的justify-content)
align-content
定义所有元素整体在行轴上的对齐方式(类似flex里面的justify-content)
css
.wrapper {
display: grid;
grid-template-columns: 100px 200px;
grid-template-rows: 100px 200px;
justify-content: space-around;
align-content: space-between;
}