grid
布局即网格布局,目前唯一一种 CSS
二维布局,是最强大的的 CSS
布局方案。它可以轻松实现以下布局,这是 flex
布局无法一次性解决的
声明定义
容器里面包含着项目元素,使用 display:grid
或 display:inline-grid
声明为网格容器。
grid
:生成一个块级(block-level
)网格inline-grid
:生成一个行级(inline-level
)网格.container {
display: grid | inline-grid;
}
flex
布局是轴线布局,只能指定 “项目” 针对轴线的位置,是一维布局,只能类似一行一行的放置grid
布局则是将容器划分成 “行” 和 “列” ,产生“单元格”,可以指定项目所在的单元格区域,是二维布局,可以随意划定放置的区域注意:只有
grid
有just-items
属性flex
没有,你可以认为flex
的just-items
被just-content
取代了
grid
算是对 flex
布局缺陷的补充,基本万能,它甚至可以轻松实现以下效果
grid
在布局的可操作性上远比flex
布局强大,但是兼容性不如flex
采用网格布局的区域,称为 “容器”( container
),应用元素 display: grid
,容器内部采用网格定位的子元素,称为 “项目”( item
)
.container{
display: grid;
}
<div class="container">
<div class="item"> div>
<div class="item">
<p class="sub-item"> p>
div>
<div class="item"> div>
div>
上面代码中, 最外层的 div
就是容器,内层的三个 div
就是项目。
注意:项目只能是容器的顶层子元素(直属子元素),不包含项目的子元素,比如上面代码的
p
元素就不是项目。grid
布局只对项目生效。
容器里面的水平区域称为 “行” ( row
),垂直区域称为 “列” ( column
),行和列隔开的格子,被称作**“单元格”**,单元格之间存在 “间距” ( gap
),单元格里放 “项目” ( item
),
一个 3
行 3
列的布局,自然会产生 9
格单元格
网格布局通过网格线来划分区域和帮助定位
容器 container
的属性如下
1. grid-template-columns(列宽)
2. grid-template-rows(行高)
3. grid-row-gap(行间距)
4. grid-column-gap(列间距)
5. grid-gap (3和4的简写,间距)
6. grid-template-areas(区域分配)
7. justify-items(主轴方向项目对齐)
8. align-items(交叉轴方向项目对齐)
9. place-items(8和9的简写)
10. justify-content(主轴内容对齐)
11. align-content(交叉轴内容对齐)
12. place-content(11和12的简写)
13. grid-auto-columns(自动列大小)
14. grid-auto-rows(自动行大小)
15. grid-auto-flow(自动流)
grid-template-columns:
定义每一列的列宽,值可是 10px
、 10%
、 10fr
。grid-template-rows:
定义每一行的行高,值同上style>
.container {
display:grid;
width: 100px;
height: 100px;
background-color: #DAE3F3;
grid-template-columns: 33.33px 33.33px 33.33px;
grid-template-rows: 33.33px 33.33px 33.33px;
}
.item{
border: 1px solid #6E2D9F;
}
style>
<div class="container">
<div class="item">div> * 9
div>
repeat()
,重复一定次数的某个数字,接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值。grid-template-columns: repeat(3,33.33px);/* 等价于 33.33px 33.33px 33.33px*/
repeat()
重复某种模式,理解为重复模板grid-template-rows:repeat(2,50px 100px 50px);/* 等价于 50px 100px 50px 50px 100px 50px*/
有时,单元格大小是固定的,但是容器大小不确定。如果希望每一行(或每一列)容纳尽可能多的单元格,它将自动填充可填入的最大值
grid-template-columns: repeat(auto-fill,33.33px);
与 auto-fill
基本类似
grid-template-columns:repeat(auto-fit,minmax(50px,1fr));
每个项目元素至少需要 50px
的宽度,每行尽可能多放项目,剩余空间够 50
并且还有项目就填充,项目数量不够就就将剩余空间平均分配给各个单元格
auto-fill和auto-fit的区别,主要是影响到元素个数比较少的情况
它们都可以与minmax
结合使用
自我理解:
auto-fill
:空列和列一样,都会其占用行空间
auto-fit
:不会产生空列,当有剩余空间时,将剩余空间平均分配给列;
国外翻译:
auto-fill
:在一行中尽可能多地容纳可能的列,即使它们是空的。
auto-fit:
将任何列装入空间。更喜欢扩展列来填充空间而不是空列。
minmax()
函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。
grid-template-columns: 1fr 1fr minmax(100px, 1fr);
上面代码中,minmax(100px, 1fr)
表示列宽不小于100px
,不大于1fr
。
fraction
的缩写,意为 “片段” 。如果两列的宽度分别为 1fr
和 2fr
,就表示后者是前者的两倍。
grid-template-columns: 1fr 2fr 3fr;
fr
可以与绝对长度的单位结合使用,这时会非常方便:例如下面会显示为第一列 100px
,剩余宽度内第三列是是第二列的二倍
.grid {
display: grid;
grid-template-columns: 100px 1fr 2fr;
}
auto
关键字表示由浏览器自己决定长度。
.grid {
display: grid;
width: 100%;
grid-template-columns: 100px auto 100px;
}
上面这段代码,可以做到左右两列 100px
,而中间自适应
grid
布局会为网格线自动命名为数字 1
~ 6
,也可以是 -6
~ -1
( -1
是最后一行的替代值),有了网格线就可以定位项目位置
grid-template-columns
属性和 grid-template-rows
属性里面,还可以使用方括号,指定每一根网格线的名字,方便以后的引用,并且可以起多个名字
.container {
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}
.grid {
display: grid;
width: 100%;
grid-template-columns: [c1] 100px [c2] auto [col-3 c3] 100px;
}
网格线命名可以重复
.container{
grid-template-columns: repeat(3 [col-start] 20px) 5%;
}
指定网格线的大小,即网格间距
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
column-gap: 10px;
row-gap: 15px;
}
注意:
grid-
前缀将被删除,并重grid-column-gap grid-row-gap
命名为column-gap and row-gap
。Chrome 68+
、Safari 11.2 Release 50+
和Opera 54+
已经支持无前缀属性。
网格布局允许指定 “区域” ( area
),一个区域由单个或多个单元格组成。 grid-template-areas
属性用于定义区域
"container">
"a" style="grid-area: a">1
"b" style="grid-area: b">2
"c" style="grid-area: c">3
"d" style="grid-area: d">4
"e" style="grid-area: e">5
justify-items
沿主轴对齐网格项目,此值适用于容器内的所有网格项,有 4
个属性值
start
- 对齐项目以与其单元格的起始边缘齐平end
- 对齐项目以与其单元格的末端边缘齐平center
- 对齐单元格中心的项目stretch
- 填充单元格的整个宽度(这是默认值).container {
justify-items: start | end | center | stretch;
}
网格项目设置
justify-self
属性可以覆盖容器的justify-items
,单独为该项目设置对齐方式
align-items
沿列轴对齐网格项目,此值适用于容器内的所有网格项,有 5
个属性值,前 4
个同上,以下为额外属性
网格项目设置
align-self
属性可以覆盖容器的align-items
,单独为该项目设置位置
place-items
是上面两个属性的简写形式
place-items: ;/*start end*/
justify-content
控制整个内容区域在容器里面的水平位置(左中右)
start
- 对齐网格以与网格容器的起始边缘齐平end
- 对齐网格以与网格容器的末端边缘齐平center
- 在网格容器的中心对齐网格stretch
- 调整网格项的大小以允许网格填充网格容器的整个高度space-around
- 在每个网格项目之间放置均匀的空间,在远端有一半大小的空间space-between
- 在每个网格项目之间放置均匀的空间,远端没有空间space-evenly
- 在每个网格项目之间放置均匀的空间,包括远端
align-content
控制整个内容区域的垂直位置(上中下),属性取值同上
有时网格的总大小可能比网格容器的小。如果您的所有网格项目都使用非灵活单位如
px
,就可以使用内容位置控制
place-content
是上面两个属性的简写形式
place-content: ;/*start end*/
grid-auto-columns
属性和 grid-auto-rows
属性用来设置,浏览器自动创建的多余网格的列宽和行高。
如果不指定这两个属性,浏览器完全根据单元格内容的大小与容器的大小,自动决定新增网格的列宽和行高。
.container {
grid-auto-columns: 10px | 10% | 1fr;
grid-auto-rows: 10px | 10% | 1fr;
}
为了说明如何创建隐式网格轨道,请考虑以下问题:
.container {
grid-template-columns: 60px 60px;
grid-template-rows: 90px 90px;
}
但现在想象一下,您使用 grid-column
和 grid-row
定位您的网格项目,如下所示:
.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}
我们告诉 .item-b
从第 5
列开始并在第 6
列结束,
但我们从未定义第 5
或 6
列。因为我们引用了不存在的线,所以会创建宽度为 0
的隐式轨迹来填充间隙。我们可以使用 grid-auto-columns and grid-auto-rows
来指定这些隐式轨道的宽度
.container {
grid-auto-columns: 60px;
}
动图解释
假如我们创建了一个 2 x 2
网格,但是我们有8
个项
<style>
.container {
display:grid;
background-color: #DAE3F3;
grid-template-columns: repeat(2,50px);
grid-template-rows: repeat(2,50px);
grid-auto-columns: 100px;
}
.item1{/*这会导致产生自动生成列*/
grid-column:5/6;
grid-row: 1/2;
background-color: #fff;
}
style>
<div class="container">
<div class="item item1">div>
<div class="item">div> * 7
div>
这时,除了最左边的 4
个单元格,其他单元格是自动生成的,浏览器会根据单元格内容的大小与容器的大小自动赋值
加入代码
grid-auto-columns: 100px;
grid-auto-flow
属性控制着自动布局算法怎样运作,精确指定在网格中被自动布局的元素怎样排列。默认的放置顺序是 “先行后列” ,即先填满第一行,再开始放入第二行,它的属性值如下
row
- 先行后列(默认)column
- 先列后行dense
- 如果稍后出现较小的项目,则告诉自动放置算法尝试在网格中填充更早的孔.container {
grid-auto-flow: row | column | row dense | column dense;
}
为了理解它我们参考如下案例
<style>
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: row;
}
.item-a {
grid-column: 1;
grid-row: 1 / 3;
}
.item-e {
grid-column: 5;
grid-row: 1 / 3;
}
style>
<section class="container">
<div class="item-a">item-adiv>
<div class="item-b">item-bdiv>
<div class="item-c">item-cdiv>
<div class="item-d">item-ddiv>
<div class="item-e">item-ediv>
section>
我们设置 grid-auto-flow
为 row
, a
和 e
的位置是固定死的,注意 b
、 c
、 d
如何在可用行中流动:
修改流的方向为列
grid-auto-flow: column;
现在情况一如果把 c
的高设为 2
,如果不使用 dense
就会出现这种情况, d
不会自动填充 b
下的剩余空间
使用 dense
之后,尝试在网格中更早的地方填充
请注意,
dense
只会更改项目的视觉顺序,并可能导致它们出现乱序,这对可访问性不利。
在单个属性中设置所有以下属性的简写: grid-template-rows
, grid-template-columns
, grid-template-areas
, grid-auto-rows
, grid-auto-columns
和 grid-auto-flow
(注意:只能在单个网格声明中指定显式或隐式网格属性)。属性值:
none
:将所有子属性设置为其初始值
:与 grid-template
简写的工作方式相同
[ [ / ] ]
:接受所有与 grid-auto-flow
, grid-auto-rows
和 grid-auto-columns
相同的值。 如果省略 grid-auto-columns
,则将其设置为为 grid-auto-rows
指定的值。如果两者都被省略,则它们被设置为它们的初始值.container {
grid: 200px auto / 1fr auto 1fr;
}
.container {
grid-template-rows: 200px auto;
grid-template-columns: 1fr auto 1fr;
grid-template-areas: none;
}
例,以下代码写法等价:
.container {
grid: column 1fr / auto;
}
.container {
grid-auto-flow: column;
grid-auto-rows: 1fr;
grid-auto-columns: auto;
}
也可用使用一个更复杂但相当方便的语法来一次设置所有内容。可以指定 grid-template-areas
、 grid-template-rows
以及 grid-template-columns
,并将所有其他子属性设置为其初始值。
例,在网格区域内,指定网格线名称和内联轨道大小:
.container {
grid:
[row1-start] "header header header" 1fr [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
以上代码等价于:
.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;
}
项目 itme
的属性如下
1. grid-column-start(列起始线)
2. grid-column-end(列结束线)
3. grid-row-start(行起始线)
4. grid-row-end(行结束线)
5. grid-column(项目列大小)
6. grid-row(项目行大小)
7. grid-area(选择区域)
8. justify-self(主轴方向自我对齐)
9. align-self(交叉轴方向自我对齐)
通过 4
条线确定项目的所在区域
grid-column-start
列起始线grid-column-end
列结束线grid-row-start
行起始线grid-row-end
行结束线它们的取值如下
|
可以是一个数字来引用编号的网格线,或者是一个名称来引用命名的网格线span
- 该项目将跨越提供的网格轨道数量span
- 该项目将跨越直到它到达具有提供名称的下一行auto
表示自动放置、自动跨度或默认跨度为 1
.item {
grid-column-start: | | span | span | auto;
grid-column-end: | | span | span | auto;
grid-row-start: | | span | span | auto;
grid-row-end: | | span | span | auto;
}
grid-column
:是 grid-column-start
和 grid-column-end
的合并简写形式grid-row
: grid-row-start
和 grid-row-end
的合并简写形式.item-c{
grid-column: 3 / span 2;
grid-row: third-line / 4;
}
如果没有指定结束行值,则该网格项默认跨越
1
个轨道
在 4.3
中我们提到过, grid-area
属性指定项目放在哪一个区域。
.e{
grid-area: e;
}
grid-area
还有另一种写法
.item-1 {
grid-area: 1 / col4-start / last-line / 6;/*行起始线 列起始线 行结束线 列结束线*/
}
覆盖容器的 justify-items/align-items
的属性
start
–
对齐网格项以与单元格的起始边缘齐平end
–
对齐网格项以与单元格的结束边缘齐平center
–
对齐单元格中心的网格项stretch
–
填充单元格的整个宽度(这是默认值)justify-self
简写
place-self
设置 align-self
和 justify-self
的简写形式
.container{
place-content: | auto;
}
如果省略第二个值,则将第一个值同时分配给这两个属性
使用 grid
时需要时刻注意它的兼容性问题,这是它的缺点,查看最新兼容性
参考资料
Grid