HTML+CSS06 Grid布局
Grid布局学习笔记。
与Flex的比较
Flexbox是一维布局系统,适合做局部布局,比如导航栏组件。Grid是二维布局系统,通常用于整个页面的规划。
二者从应用场景来说并不冲突。虽然Flexbox也可以用于大的页面布局,但是没有Grid强大和灵活。二者结合使用更加轻松。
兼容性
兼容性并不乐观,虽然至2017年3月,许多浏览器都提供了对 CSS Grid 的原生支持,但是都体现在比较新版本上:
基本概念
Grid容器里面,水平区域成为行,垂直区域称为列,行和列的交叉区域成为单元格(cell)。正常情况下n
行m
列会产生n x m
个单元格。
划分网格的线就成为网格线,n
行有n+1
根水平网格线,m
列有m+1
根垂直网格线
一个4x4
的网格,共有5根水平网格线和5根垂直网格线
容器属性
改变容器
使用display: grid
指定容器采用网格布局(或者使用display: linline-grid
指定容器采用行内网格布局)。
设为网格布局后,容器子元素的float
、display: inline-block
、display: tabel-cell
、vertical-align
和column-*
设置都会失效
划分网格
容器指定了网格布局后需要划分行和列:
grid-template-columns
属性定义每一列的列宽grid-template-rows
属性定义每一行的行高
1 | .container { |
上面的代码将容器划分为三行散列的网格,列宽和行高都是100px
fr
关键字
划分网格的宽度单位除了是px
、百分比等常规单位之外,也可以使用fr
关键字,如果两列的宽度是1fr
和2fr
,那么代码后者的宽度是前者的两倍
如果同时使用px
和fr
时,使用fr
的宽度会将剩余的宽度都充满
repeat
函数
可以使用repeat
函数来书写重复的值,它接受两个参数,第一个是重复的次数,第二个是重复的值
1 | .container { |
auto-fill
关键字
在使用repeat
函数时,可以使用auto-fill
关键字,表明在容器大小不确定时,希望每一行或者每一列容纳尽可能多的单元格
1 | .container { |
上面代码表示每列宽度是100px
,然后自动填充,直到不能放置更多的列
网格线名称
grid-template-columns
属性和grid-template-rows
属性里面,可以使用[]
指定每一根网格线的名字,方便后面引用
1 | .container { |
上面的代码,将列的网格线分别命名为a
、b
、c
,后面引用的时候可以直接使用名称
网格间距
grid-row-gap
,设置行间距grid-column-gap
,设置列间距grid-gap
,是上面两者的缩写
grid-gap
需要两个参数:
1 | .container { |
如果省略的第二个值,浏览器认为第二个值等于第一个值
最新的标准中,上面三个属性的
grid-
前缀都已经删除,直接使用row-gap
、column-gap
、gap
即可
划分区域
使用grid-template-areas
将一个网格的划分成为各个命名的区域,一个区域由单个或多个单元格组成:
1 | .container { |
要注意的是,grid-template-areas
的属性包含的区域数量一定要和网格划分后的总数一致。上面的代码会划分出9个单元格,然后将其命名为a
到i
的九个区域,分别对应多个单元格
多个单元格合并为一个时使用同一个命名即可(注意,不相邻的单元格不可以使用同一个命名)
1 | .container { |
如果某些区域用不到,使用.
表示:
1 | .container { |
对区域的命名会影响到网格线,每个区域的起始网格线会命名为区域名-start
,终止网格线会自动命名为区域名-end
网格填充顺序
划分网格之后,容器的子元素会按照顺序放到每一个网格,默认的放置顺序是先行后列
,即先填满第一行,再开始放入第二行
grid-auto-flow
属性决定了这个顺序,默认取值是row
,即先行后列的顺序进行放置,其他取值有:
column
,先列后行row dense
column dense
后两个取值用于指定如果出现剩余空间后如何摆放,例如1
和2
各占两个单元格,在默认情况下第一行会出现空格:
如果修改为row dense
,表示先行后列,并且尽可能紧密填满,尽量不出现空格,这时候3
就会部位到第一行
单元格内容对齐
justify-items
,设置单元格内容水平位置,取值start
/end
/center
/center
align-items
,设置单元格内容的垂直位置,取值start
/end
/center
/center
place-items
,上面两个属性的缩写,如果省略第二个值认为与第一个值相等
justify-items
取start
时:
容器对齐
justify-content
,设置整个内容区域在容器里面的水平位置,取值start
/end
/space-around
/space-between
/space-evenly
align-content
,设置整个内容区域在容器里面的垂直位置,取值start
/end
/space-around
/space-between
/space-evenly
justify-content
取start
时:
justify-content
取space-between
时:
缩写
grid-template
属性grid-template-columns
、grid-template-rows
和grid-template-areas
这三个属性的合并简写形式。
grid
属性是grid-template-rows
、grid-template-columns
、grid-template-areas
、 grid-auto-rows
、grid-auto-columns
、grid-auto-flow
这六个属性的合并简写形式。
项目属性
分配网格
grid-column-start
,左边框所在的垂直网格线grid-column-end
,右边框所在的垂直网格线grid-row-start
,上边框所在的水平网格线grid-row-end
,下边框所在的水平网格线
通过这一组属性,指明网格的起始位置,取值可以指定为第几根网格线(从1
开始),也可以使用之前网格线的命名网格线
属性取值还可以使用span
关键字,表示跨越,及这个单元格跨越多少网格,如果出现重叠使用z-index
指定重叠顺序
一般情况下我习惯使用下面的两个缩写来分配项目占据的网格:
grid-column
,grid-column-start
和grid-column-end
的合并简写形式grid-row
,grid-row-start
属性和grid-row-end
的合并简写形式
1 | .item-1 { |
缩写方式中仍然可以使用命名网格线和span
关键字
如果省略/
及后面的部分,则默认跨域一个网格
分配区域
grad-ared
属性指定项目放在哪个区域,取值就是之前在grid-template-areas
中指定的区域名。它还可以作为grid-row-start
、grid-column-start
、grid-row-end
、grid-column-end
的合并简写:
1 | .item-1 { |
指定项目位置
justify-self
,设置单元格内容的水平位置,与justify-items
属性用法一致,但只作用于的单个项目align-self
,设置单元格内容的垂直位置,与align-items
属性用法一致,但只作用于的单个项目place-self
,上面二者的缩写
实例
两栏布局
1 |
|
圣杯布局
1 | <div class="container"> |
可以使用网格线来实现:
1 | .container { |
也可以使用区域来实现:
1 | .container { |