CSS栅格系统总结
栅格系统可以看作由网格做成,类似于表格的结构,但是数据放置方式不同于表格。且栅格系统有一定的兼容性问题。
栅格相关元素
栅格系统的使用步骤:
- 声明网格项目
- 绘制栅格线(绘制轨道)
- 将元素填入网格项中
1 声明网格项目
如果某元素声明为网格项目display:grid
,那么该元素内部的子元素的布局方式则由父元素的规则来定义。
网格项目有两种:块级容器、行内块级容器
-
块级容器
display: grid;
声明为此方式的盒子表现为块级元素的特性。
-
行内块级容器
diplay: inline-grid;
声明此方式的盒子表现为行内块级元素的特性。
2 栅格线绘制
2.1 默认栅格线绘制设定
grid-auto-rows
用于指定隐式创建的行轨道大小
grid-auto-columns
用于指定隐式创建的列轨道大小
关键字属性值
-
auto(默认值)
根据网格项目大小以及元素单元分配进行自定义
-
min-content/max-content
指定网格项目中的网格元素中占用空间最小/最大的那个决定轨道的尺寸
数值属性值
-
px
用于直接指明轨道的大小,非负数。
百分比属性值
-
%
该值相对于网格项目大小来进行设定的
弹性属性值
-
fr
类似于%,通过指定fr,来划分轨道占用网格项目的份数。但是不同于%单位的是,此单位弹性分配剩余空间,更加的灵活。
MDN这样描述的:按其弹性因子的比例挤占剩余空间的一部分。
grid-auto-rows: 50% 1fr 2fr;
以上表明第一个轨道行占容器50%,剩下两个各占剩余空间的1/3和2/3。
最小最大属性值
-
minmax(min,max)
函数符号,定义一个不小于min且不大于max的轨道大小,也即轨道大小的值按照自适应方式指定,且在min~max区间中。
以上几个属性值可以自由组合
当没有使用grid-template-rows指明轨道大小的时候,会使用grid-auto-rows
来进行指定大小。
当栅格无法放置内容的时候,系统会自动添加栅格用于放置溢出的元素。
可以通过grid-auto-rows/grid-auto-columns
来自定义自动添加的栅格单元格大小
选项 | 说明 |
---|---|
grid-auto-rows | 控制自动增加的栅格行的尺寸,grid-auto-flow:row; 为默认 |
grid-auto-columns | 控制自动增加的栅格列的尺寸,grid-auto-flow: column; |
2.2 栅格线绘制
grid-template-rows
用于绘制行
grid-template-columns
用于绘制列
确定属性值
-
none
不显示指明栅格线,所有的行列的大小由
grid-auto-rows/columns
隐式指定 -
百分比
% em等百分比单位,其值相对于栅格容器的大小
-
px
用于指定特定的长度值
-
min-content/max-content
以元素中最小/最大内容最为轨道大小
-
auto
自适应分配剩余空间。
指明范围属性值
-
minmax(min,max)
轨道大小严格控制在min和max之间,且根据容器的大小进行变化
重复属性值
-
repeat([重复次数,auto-fill,auto-fit], 重复大小)
属性值
-
px
指明重复的大小
-
%
-
fr
-
min/max-content
-
auto-fill
自动填充,填充次数 = Math.floor(网格项目大小 / 重复大小)
height: 300px; grid-template-rows: repeat(auto-fill,100px);
以上代码表明:每一行的大小为 100px 重复 300px / 100px = 3 次。也即总共绘制了三行栅格线。
假如容器大小 / 重复大小不是整数,那么会产生剩余空间,而剩余空间会再次均匀的分配给预绘制的栅格轨道中,也即:
height: 250px; grid-template-rows: repeat(auto-fill,100px);
每一行大小为100px,重复2次,则总共绘制两条栅格线。剩余空间为50px。那么50px / 2 = 45px,会被添加到两个绘制的栅格轨道中。
绘制好了栅格线之后,元素会进行填充到单元格中,如果元素没有填充完单元格,那么剩余的轨道就会依然会被保留。
-
auto-fit
与auto-fill类似,都是对先尽可能多的创建轨道,不足一个轨道的空间平均分配给已有的轨道,但是不同于auto-fill的是,如果元素没有填充完单元格(轨道),剩余的轨道会被折叠,并将空轨道全部平均分配给已有元素的轨道。(也即发生空白轨道折叠的情况)
-
auto-fill与auto-fit的区别
主要在于元素没有填充完单元格(轨道),分配好的空轨道处理的问题,auto-fill保留空轨道,auto-fit平均分配空轨道(轨道折叠)。
-
当栅格线绘制的行与列的总空间小于网格项目总体的空间的时候,多余的空间以空白方式显示。
当栅格线绘制的行与列的总空间大于网格项目总体空间的时候,绘制的单元格会溢出到网格项目外部
由于如果不指明元素占多少个单元格,那么默认元素占一个单元格。而此处所谓的占用一个单元格,意思是元素放置在单元格空间内,如果指明了元素的大小且小于单元格大小,则元素仅占用单元格自身大小的空间(如上图所示),如果没有指明元素大小,则默认撑满整个单元格的空间。
2.3 组合写法
grid-template
是grid-template-rows
和grid-template-columns
和grid-template-area
的简写方式
简写的方式:
grid-template-rows / grid-template-columns
grid-template: 100px repeat(2,50px) / 200px repate(2,100px);
以上指明了三行三列的栅格
grid-template-area grid-template-rows / grid-template-columns
grid-template: 'a b b' 100px repate(2,100px) / 200px repate(2,100px);
以上定义了两个区域,且在这两个区域中指定了三行三列的栅格单元
3 间距设定
和表格元素一样,栅格系统中网格单元格之间也存在着间距。随着这些间距可以通过单元格自身的属性进行设定,比如:margin padding等进行控制。
<main>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</main>
<style>
main {
width: 300px;
height: 300px;
margin: 0 auto;
border: 1px solid black;
display: grid;
grid-template-rows: repeat(auto-fill,150px);
grid-template-columns: repeat(auto-fill,100px);
}
div {
background: linear-gradient(45deg,darksalmon,pink);
box-sizing: border-box;
// 通过padding 来进行控制网格单元格之间的距离
padding: 20px;
background-clip: content-box;
}
</style>
但是栅格系统中提供有关于网格单元格之间的距离的控制。
grid-row-gap/grid-column-gap
分别可以设定行/列间距
以上的写法为最初的写法,之后可以采用row-gap/column-gap
同样可以设定。后面这种写法更简洁一些。
<style>
main {
width: 300px;
height: 300px;
margin: 0 auto;
border: 1px solid black;
display: grid;
grid-template-rows: repeat(2,140px);
grid-template-columns: repeat(3,90px);
// 最开始的一种写法
/*grid-row-gap: 20px;*/
// 之后的一种写法
row-gap: 20px;
column-gap: 15px;
}
div {
background: linear-gradient(45deg,darksalmon,pink);
box-sizing: border-box;
background-clip: content-box;
}
</style>
gap
是row-gap
和column-gap
的简写方式
gap: row-gap column-gap
如果只写一个值,那么表示同时设定行和列间距
4 元素定位
元素默认放在一个网格单元格中,如果元素的大小比一个单元中的大小大,那么多余的部分会被隐藏。
但是实际的开发中,元素不止占用一个单元格。因此需要设定元素占用多少个单元格。
4.1 通过栅格线编号
当绘制栅格系统的时候,系统默认会为每一个栅格线进行编号。
知道了栅格系统中每一个栅格线的编号之后,如果去将元素放置到指定的单元格中呢。
一般确定一个矩形,知道矩形在水平方向的开始位置和结束位置,以及垂直方向的开始位置和结束位置,就可以很好的绘制出一个矩形来。
在css栅格中通过grid-row-start/grid-row-end
指明元素所占的单元格的行开始以及行结束
通过grid-column-start/grid-column-end
指明元素所占的单元格的列开始以及列结束
div {
// 指明元素所占的单元格的起始位置
grid-row-start: 1;
grid-row-end: 2;
grid-column-start: 1;
grid-column-end: 3;
background: linear-gradient(45deg,darksalmon,pink);
box-sizing: border-box;
background-clip: content-box;
}
注意:栅格系统只能放置为矩形,而不能是不规则图形。
4.2 通过命名栅格线的方式
可以自定义的方式给每一个栅格线进行命名
4.2.1 固定命名栅格线
跟系统对栅格线进行编号一样,可以对每一条栅格线进行命名。
书写规则:用[]
进行包裹
grid-template-rows: [r1-start] 150px [r1-end r2-start] 150px [r2-end];
grid-template-columns: [c1-start] 100px [c1-end c2-start] 100px [c2-end c3-start] 100px [c3-end];
[]
中是对每一条线的命名,每一条线可以对应多个名字
使用命名的线
div {
// 使用命名的栅格线 由于一根线命名不止一个 只要是该线的命名 都可以写 但是为了更加语义化 更加建议按照start 和 end 的方式来进行书写 避免造成混乱 以至于弄错
grid-row-start: r1-start;
grid-row-end: r1-end;
grid-column-start: c1-start;
grid-column-end: c2-end;
background: linear-gradient(45deg,darksalmon,pink);
box-sizing: border-box;
background-clip: content-box;
}
4.2.2 重复命名栅格线
使用固定命名栅格线的方式,在线比较多的情况下代码量会增多。如果栅格单元大小有一定的规律,可以采取重复命名的方式。
grid-template: repeat(2,[r-start] 100px [r-end]);
同样在每一条线的开始和结束进行命名操作。
[]
中采取的是自定义的方式
那如何应用自定义命名的栅格线呢?
采用自定义名称+系统编号
div {
// 采用自定义名称+系统编号的方式引用
grid-row-start: r-start 1;
grid-row-end: r-end 1;
grid-column-start: c-start 1;
grid-column-end: c-end 2;
background: linear-gradient(45deg,darksalmon,pink);
box-sizing: border-box;
background-clip: content-box;
}
这里仍然采取了系统编号,那为什么不直接使用系统编号,而要多写一些内容自定义名称呢?不是会显得更加麻烦么?
采用自定义的方式命名栅格线,会让代码书写的过程中更具有语义化。
4.3 通过偏移量的方式
可以通过偏移量的方式指定元素占据的单元格位置。
span
用于指定相对于-start
的偏移量,可以是编号也可以是自定义名称。
没有特别指明-start
的情况下,默认是1
div {
// 相对于grid-column-start 偏移 2跟线
grid-column-end: span 2;
background: linear-gradient(45deg,darksalmon,pink);
box-sizing: border-box;
background-clip: content-box;
}
4.4 简写方式
可以使用grid-row和grid-column
直接定义栅格线行和列的开始和结束位置
书写规则:
行和列的开始和结束位置采用/
隔开
grid-row: 1/span 3;// 表示从第一根线开始 偏移三根线 到第四根线结束
元素值可以是栅格线的编号/ 自定义命名 / 偏移量
如果只写一个属性值,那么-start
默认为1
4.5 采用区域的方式
可以采用区域的一个小特性来实现类似于边线定位的效果。
grid-area: 行开始/列开始/行结束/列结束
属性值可以是系统编号/自定义命名/偏移量
div {
grid-area: 1/2/2/3;
background: linear-gradient(45deg,darksalmon,pink);
box-sizing: border-box;
background-clip: content-box;
}
5 区域定位
类似于使用grid-row一样,可以指定元素占用的单元格的位置。此外还可以使用区域的方式设定元素占用的单元格的位置。
- 首先对网格项目进行栅格线的绘制
<div>
<header></header>
<nav></nav>
<main></main>
<footer></footer>
</div>
<style>
div {
width: 400px;
height: 500px;
margin: 0 auto;
border: 1px solid black;
display: grid;
grid-template-rows: 60px 1fr 60px;
grid-template-columns: 60px 1fr;
}
</style>
可以看到网格项目被分为上下三个部分,左右两个部分的形式。
- 此时我们可以使用
grid-template-areas
来对已经划分出来的网格单元格来进行命名。
div {
width: 400px;
height: 500px;
margin: 0 auto;
border: 1px solid black;
display: grid;
grid-template-rows: 60px 1fr 60px;
grid-template-columns: 60px 1fr;
grid-template-areas: 'header header'
'nav main'
'footer footer';
}
多个同名的,跨域相邻的行/列的单元称为网格区块。非矩形的网格区块是无效的。
注意:当对单元格进行区域命名的时候,系统会自动对命名的区域的边线进行命名。
比如:nav区域四周的边线命名为:
因此可以通过此方式来设置元素所占用的单元格的位置。
-
设定元素占用的单元格的位置
使用
grid-area: 指定的区域的名称
来设定元素占用的区域也即单元格的位置。div { width: 400px; height: 500px; margin: 0 auto; border: 1px solid black; display: grid; grid-template-rows: 60px 1fr 60px; grid-template-columns: 60px 1fr; grid-template-areas: 'header header' 'nav main' 'footer footer'; } header, nav, main, footer { background: linear-gradient(45deg,yellow,pink); box-sizing: border-box; background-clip: content-box; padding: 5px; } header { // 占用区域名称为header的单元格 grid-area: header; } nav { // 占用区域名称为nav的单元格 grid-area: nav; } main { // 占用区域名称为main的单元格 grid-area: main; } footer { // 占用区域名称为footer的单元格 grid-area: footer; }
以上是通过区域的方式来设置元素所占用的单元格的位置。
由于当设定了区域之后,系统会自动给每一条边线命名。因此也可以通过设定的命名来对元素所占用的单元格进行设定。
header {
grid-area: nav-start/ nav-start / nav-end / nav-end;
background: linear-gradient(45deg,yellow,pink);
}
5.1 区域占位
可以对多个单元格命名相同的区域,但是有时并没有必要全部都要进行区域的命名,此时可以通过占位符.
来进行占位。
使用一个或多个 连续的.
定义区域占位。
以上面的例子来修改,此时只需要对底部两个单元格进行区域命名,其他的单元格不变。
grid-template-areas: '. .'
'. .'
'footer footer';
其中一个.
表示一个单元格的名称,只是不去显示命名而已。
6 栅格流动
在网格项目中设置grid-auto-flow
属性可以改变单元格排列方式。一般情况下,单元格的排列是从左到右的方式,但是也可以改为从上往下的方式来进行排列。
属性值 | 说明 |
---|---|
column | 按列排序 |
row | 按行排列 |
dense | 元素使用前面空余栅格 |
查看以下代码:
<main>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</main>
<style>
main {
width: 300px;
height: 300px;
border: 1px solid black;
margin: 100px auto;
display: grid;
grid-template-rows: repeat(3,100px);
grid-template-columns: repeat(3,100px);
grid-auto-flow: row;
}
div {
background: linear-gradient(45deg,yellow,pink);
padding: 10px;
box-sizing: border-box;
background-clip: content-box;
}
div:nth-of-type(1){
grid-column: 1/3;
}
div:nth-of-type(2) {
grid-row: 2/3;
grid-column: 2/3;
}
</style>
可以看到剩余的元素会占用空余的空间。(但是没有设置dense就是这样了,有一点迷,为啥不是空白位被保留)
7 对齐管理
7.1 网格项目对齐方式
当网格项目大于栅格的尺寸的时候,需要考虑整体元素的对齐方式。
可以采用justify-content
来设置grid-auto-flow
设定的流动方向的对齐方式
采用align-content
来设置与grid-auto-flow
设定的流动方向垂直的对齐方式
两者的用法与在弹性布局中属性的使用方式是一致的。
main {
width: 300px;
height: 300px;
border: 1px solid black;
margin: 100px auto;
display: grid;
grid-template-rows: repeat(2,50px);
grid-template-columns: repeat(3,50px);
justify-content: center;
align-content: center;
}
div {
background: linear-gradient(45deg,yellow,pink);
padding: 10px;
box-sizing: border-box;
background-clip: content-box;
}
7.2 栅格元素整体对齐方式
单元格中放置的元素,如果没有撑满整个单元格,此时可以设置元素在单元格中的位置。除了可以对单元格内元素采用弹性布局中justify-content
等属性进行设置,栅格系统中也提供了相对应的方式来实现元素的对齐方式。
justify-items
用于控制元素在单元格水平方向的对齐方式。(此处水平指的是水平方向,而不是grid-auto-flow
所指定的栅格排列方向)
属性值 | 说明 |
---|---|
start | 元素对齐单元格的左边 |
end | 元素对齐单元格的右边 |
center | 元素对齐单元格的中间 |
stretch | 水平撑满单元格(默认,如果没有设置高度/宽度的情况下) |
align-items
用于控制元素在单元格垂直方向的对齐方式(此处垂直指的是垂直方向,而不是grid-auto-flow
指定的栅格排列方向相垂直的方向)
属性值 | 说明 |
---|---|
start | 元素对齐单元格的顶部 |
end | 元素对齐单元格的底部 |
center | 元素对齐单元格的中间 |
stretch | 垂直撑满单元格(默认,如果没有设置高度/宽度的情况下) |
不同于justify-content align-content
是当一个轨道中元素没有占满单元格时,整体轨道中元素的对齐方式。
而justify-items和align-items
用于控制栅格内的整体元素在当前所处的单元格内的对齐方式
justify-items: center;
7.3 单个栅格元素对齐方式
可以通过justify-self
和align-self
来控制单个元素在自己所处的单元格的对齐方式。
用法和justify-items align-items
一致。
div:nth-of-type(1) {
justify-self: start;
}
7.4 简写方式
可以使用place-
来进行简写以上三种对齐方式。
place-content: align-content justify-content;
place-items: align-items justify-items;
place-self: align-self justify-self;
第一个属性值设定的是垂直方向的对齐方式,第二个元素设定的是水平方向的对齐方式。两者不可交换顺序。
div:nth-of-type(1) {
place-self: end center;
}
8 grid简写
grid是简写属性,可以用来设置:
- 显式网格属性 grid-template-rows、grid-template-columns和 grid-template-areas,
- 隐式网格属性 grid-auto-rows、grid-auto-columns 和 grid-auto-flow,
- 间距属性 grid-column-gap和 grid-row-gap
语法:
<'grid-template'> | <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? | [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>
-
<'grid-template'>
grid: repeat(2,100px) / 100px 100px 100px;
-
<'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>?
grid: 100px 100px / auto-flow dense repeat(2,100px);
其中auto-flow为关键字,写了auto-flow表明为column
-
[ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>
grid: auto-flow / 200px;