创建网格容器
网格容器(
grid container
)是一个为其内容定义网格格式上下文(grid formatting context
)的元素。网格又 2 种,
dispaly:grid;
和dispaly:inline-grid;
。wang’g被浮动的元素不会侵入网格容器,即网格不会滑动至浮动元素下
网格容器的边距不会与其后代元素(第一个或最后一个子元素)的边距 折叠。
基本网格术语
网格容器(grid container)
是一个建立网格格式上下文的盒子,并根据网格布局规则布局元素的区域。网格项(grid item)
是 在网格格式上下文中参与网格布局的内容。通常是网格容器的子元素,也可以是匿名的文本。网格轨道(grid track)
是两个相邻网格线之间的空间。换句话说,就是一个网格行(grid row)
或网格列(grid column)
网格单元格(grid cell)
是由四条网格线限定的空间,类似于表格单元格。网格单元格不能直接用 CSS 网格属性来控制。网格区域(grid area)
是由一个或多个网格单元格组成的一个矩形区域。网格区域可以通过 CSS 网格属性直接控制。- 网格轨道,网格单元格,网格区域完全由网格线构成,它不必与网格项对应,不需要在每一个网格区域都填入一个网格项
网格线的布局
网格线的控制,先从两个密切相关的属性开始grid-template-rows
,grid-template-columns
网格线可以通过编号、命名或将它们混合在一起来引用。
固定宽度的网格轨道
1
2
3
4
5
6
7
8#grid {
display: grid;
grid-template-columns: 200px 50% 100%;
}
#grid {
display: grid;
grid-template-columns: [start col-a] 200px [col-b] 50% [col-c] 100px [stop end last];
}弹性网格轨道
fr
单位,在一系列长度值周分配剩余空间,如果指定了多个部分,则剩余空间根据各自的系数按比例分配。例如grid-template-columns: 1fr 1fr 1fr
,则网格容器的宽度 3 等分,每个列的宽度各占 1 份。
minmax(min,max)
定义了一个长宽的闭区间,与网格布局一起使用。- 每个参数,可以是
<length>(非负长度)
、<percentage>
、<flex>
、max-content(网格轨道长度自适应内容最大的那个单元格)
、min-content(网格轨道长度自适应内容最小的那个单元格)
、auto
之一。 - 如果最大值小于最小值,则最大值被忽略,其被看成最小值
<flex>
值最为最小值无效。单位为fr
,指定网格轨道弹性布局的系数值,并按其系数值比例均匀分配剩余空间auto
作为最大值,等价于max-content
,作为最小值,表示网格轨道中单元格最小长宽(min-width, min-height)的最大值。
- 每个参数,可以是
fit-content(argument)
类似于minmax(min-content, max-content)
,只是参数的值设置了一个上限。等价于min(max-content, max(min-content, argument))
1
2
3
4
5#fit-content {
dislay: grid;
grid-template-columns: fit-content(50ch) fit-content(50ch) fit-content(50ch);
font-family: monospace;
}
第二列中图片宽 500px,比 50ch 更宽。max(min-content,50ch)
的结果是min-content,500px
,min(max-content,500px)
结果是 500px。所有第二列500px 宽。repeat(n,width1,width2, ... windthN ),重复网格线
1
2
3
4#grid {
display: grid;
grid-template-columns: repeat(4, 10px [col-start] 250px [col-end]) 10px;
}auto-fill
,创建一个简单模式并重复,直到填满网格容器1
2
3
4#grid {
display: grid;
grid-template-columns: repeat(3,20em) repeat(auto-fill,2em);
}一个也可以编写
grid-template-columns: repeat(auto-fill,2em) repeat(3,20em);
,因为网格布局算法首先将空间分配给固定轨道,然后再用自动重复轨道填充剩余空间。
网格区域(grid-template-areas)
1 | #grid { |
grid-template-areas
值中的每一个网格标识符对应于一个网格单元格,具有相同名称的单元格会合并到一个单独区域,**且该区域必须是矩形,如果是其他形状,则整个样式template
无效,例如grid-template-areas: "h h h h" "l c c r" "l l f f"
,l
区域的形状不是矩形,像一个L 形
**。- 如果只希望定义一些网格单元格作为网格区域,而不标记其他单元格,则使用
.
字符来填充那些未命名的单元格。1
2
3
4
5
6
7#grid {
display: grid;
grid-template-areas:
"header header header header"
"left ... ... right"
"footer footer footer footer"
}
将元素附加到网格
使用列线、行线
grid-row-start
,grid-row-end
,grid-column-start
,grid-column-end
,即“把元素的边缘依附于网格线”- 使用网格线编号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22.grid {
display: grid;
width: 50em;
grid-template-rows: repeat(5,5em);
grid-template-columns: repeat(10,5em);
}
.one {
grid-row-start:2;
grid-row-end: 4;
grid-column-start: 2;
grid-column-end: 4;
}
.two {
grid-row-start:1;
grid-row-end: 3;
grid-column-start: 5;
grid-column-end: 10;
}
.three {
grid-row-start:4;
grid-column-start: 6;
} - 使用
span
关键字,表示跨越多少网格轨道,例如上例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18.one {
grid-row-start: 2;
grid-row-end: span 2;
grid-column-start: 2;
grid-column-end: span 2;
}
.two {
grid-row-start: 1;
grid-row-end: span 2;
grid-column-start: 5;
grid-column-end: span 5;
}
.three {
grid-row-start: 4;
grid-row-end: span 1;
grid-column-start: 6;
grid-column-end: span; // span 后缺少数字,默认为 1
} - 使用网格线名称在定义网格区域时,浏览器会根据单元格名称,会使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#grid {
display: grid;
grid-template-areas:
"header header header header"
"leftside content content rightside"
"leftside footer footer footer"
}
#masthead {
grid-row-start: header;
grid-column-start: header;
grid-row-end: header;
}
#sidebar {
grid-row-start: 2;
grid-row-end: 4;
grid-column-start: leftside / span 1;
}
#main {
grid-row-start: content;
grid-row-end: content;
grid-column-start: content;
}
#navbar {
grid-row-start: rightside;
grid-row-end:3;
grid-column-start: rightside;
}
#footer {
grid-row-start: 3;
grid-row-end: span 1;
grid-column-start: footer;
grid-column-end: footer;
}name-start
或name-end
给 其两边的网格线命名。所以grid-column-start: header;
是等价于grid-column-start: header-start;
grid-column
,grid-column
简写属性.grid-column: start / end
是grid-column-start
和grid-column-end
的简写属性.
- 使用网格线编号
使用网格区域
grid-area
,将元素分配到 先前定义的网格区域1
2
3
4
5
6
7
8
9
10
11
12#grid {
display: grid;
grid-template-areas:
"header header header header"
"leftside content content rightside"
"leftside footer footer footer"
}
#masthead {grid-area: header;}
#sidebar {grid-area: leftside;}
#main {grid-area: content;}
#navbar {grid-area: rightside;}
#footer {grid-area: footer;}grid-area
属性是grid-row-start, grid-column-start, grid-row-end,grid-column-end
的简写属性。例如:1
2
3item8 {
grid-area: 1 / 2 / 5 / 6;
}item8开始于
row-line 1
,column-line 2
,结束于row-line 5
,column-line 6
网格流
如果没有显示的放置网格项,则自动将它们放置到网格中。在有效的网格流中,网格项被放置在第一个适合它的区域。最简单的情况就是按顺序填充一个网格轨道,一个网格项接着一个。如果有显示的和自动放置的网格项混合,后者必须围绕着前者工作。
grid-auto-flow
定义了网格流模式,行优先 或 列优先1
2
3
4
5
6
7
8
9
10#grid {
display: grid;
width: 45em;
height: 8em;
grid-auto-flow: row;
}
#grid li {
grid-row: auto;
grid-column: auto;
}当网络流中的元素大小超出网格项。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#grid {
display: grid;
grid-template-rows: repeat(3, 50px);
grid-template-columns: repeat(4, 50px);
grid-auto-rows: 50px;
grid-auto-columns: 50px;
}
img {
grid-row: auto;
grid-column: auto;
}
img.wide {
grid-column: auto / span 2;
}
img.tall {
grid-column: auto / span 2;
}- 在网格流中,如果一个网格单元格的空间不足放置下一个网格项,则网格项会跨域多个网格单元格。
- 在行的网格流中,其工作方式是,从左到右遍历每一行,如果有单元格空中,就把网格项放在那里。所以,item 13 在 item 11 的右边
dense
关键字会让网格流中网格项放置的更加紧密,grid-auto-flow: row dense;
,grid-auto-flow: column dense
自动的网格线
当一个网格项脱离边缘时,会根据需求添加行或列,以满足相关项的布局。一般情况下,自动添加的行或列的是需要的最小大小(即内容大小)。如果想对它们的大小施加更多控制,可以使用grid-auto-rows
和grid-auto-columns
。如下图左边设置了grid-auto-row
大小,右边没有。
grid 属性简写
该语法比较复杂,不建议使用。
1 | #grid { |
网格项(网格轨道)之间间隔
gutter
就是两个网格轨道之间的空间,就像通过扩展网格线之间的实际宽度。
通过grid-row-gap
或grid-column-gap
grid-gap
属性简写<grid-row-gap> <grid-column-gap>
1
2
3
4
5
6#grid {
display: grid;
grid-template-rows: 5em 5em;
grid-template-columns: 15% 1fr 1fr;
grid-gap: 12px 2em;
}
网格项与盒模型
基本工作原理:元素通过它的 margin 边缘来与网格连接。正边距将元素的可见部分从其占用的网格区域内推,负边距相反。
1
2
3
4
5
6
7
8
9
10
11#grid {
display: grid;
grid-template-rows: repeat(2,100px);
grid-template-columns: repeat(2, 200px);
}
.box02 {
margin: 25px;
}
.box03 {
margin: -25px 0;
}同块级布局相似,在网格布局中,也可以使用
margin
的auto
来将元素居中。1
2
3
4
5
6.i01 {margin: 10px;}
.i02 {margin: 10px; margin-left: auto};
.i03 {margin: auto 10px auto auto};
.i04 {margin: auto};
.i05 {margin: auto auto 0 0};
.i06 {margin: 0 auto};网格项是绝对定位;如果已经定义了网格线的开始和结束,则该网格区域被用作为包含块和定位上下文,而网格项将定位在该上下文中。这意味着偏移量属性是根据网格区域计算的
1
2
3
4
5
6
7
8
9.exel {
grid-row: 2 / 4;
grid-column: 2 / 5;
position: absolute;
top: 1em;
bottom: 15%;
left: 35px;
right: 1rem;
}
对齐控制
网格布局的对齐方式同弹性盒子布局很相似。
Property | Aligins | Applied to |
---|---|---|
justify-content | The entire grid in the inline(horizontal) direction | Grid container |
justify-items | All grid items in the inline direction | Grid container |
justify-self | A grid item in the inline direction | Grid items |
align-self | A grid item in the block(vertical) direction | Grid items |
align-items | All grid items in the block direction | Grid container |
align-content | The entire grid in the block direction | Grid container |
单个
item
的 对齐方式,justify-self
,align-self
所有
items
的对齐方式,justify-items
,align-items
整个
grid
的对齐方式,justify-content
,align-content
层级与顺序
- 网格项在视觉上的重叠顺序,就是在文档源中的顺序。
- 同定位一样,可以使用
z-index
来调整元素在 z 轴上的位置。 - 网格项的
order
属性也会影响其重叠顺序。