初识Grid布局
这里谈论的网格布局不是Bootstarp中的网格布局(貌似前几天Bootstarp发布v4.0版本了~),而是浏览器支持的一种新的布局方式。之前虽然略有耳闻,但一直没有去了解,最近发现貌似浏览器的支持还不错,于是决定系统地学习一下。
好像很久没有正儿八经地学习CSS了~
建议使用Chrome或Firefox运行相关代码,可以直接看见相关的网格辅助虚线,十分方便。
参考:
网格
要在某个容器上使用网格布局,只需要声明即可
display: grid
该容器下的第一代子元素(包括块级元素和内联元素)都会在网格中进行布局。
对于网格布局,我的理解是:想象成在容器上画横线和竖线,将容器变成一张网格,然后将其子元素摆放到指定的格子上,从而实现子元素的布局
其中由横线和竖线划分的最小格子,被称为网格单元;容器子元素所占据的位置,被称为网格区域
上面这个过程包含了几个概念:
- 画横线,画竖线
- 指定子元素的位置
还有几个隐含的概念:网格单元的宽度和高度、子元素之间的重叠等。接下来我们来看看这几个概念对应的语法
grid-template-columns
用来确定网格的列数,以及每一列的宽度
grid-template-columns: 200px repeat(3, 10px) 1fr;
- 每一列用空格分隔
repeat
函数用于生成重复的列,第一个参数是重复的数量,第二个参数是一个轨道列表(也可以使单个列)- 当显示指定列数后,即使列宽总和没有填满总容器的高度,或者容器宽度发生改变,列数也是不会发生改变的,
- 数量还支持
auto-fill
关键字,表示根据容器宽度自动生成最大宽度为第二个参数的列轨道,数量由容器宽度控制
- 支持任何CSS长度单位,除此之外还提供了
fr
单位,表示网格容器可用空间的一等份,跟flex-grow
属性的作用类似,当混合使用固定长度单位和fr时,会从总容器尺寸中减去已被使用的,再计算fr代表的尺寸 - 列宽度的优先级大于子元素本身的宽度,即不会由于子元素自身的宽度改变列宽,因此可以实现类似于负
margin
的效果 - 在网格布局中,子元素的盒子模型以
box-sizing:border-box
处理
当声明了列数n之后,默认情况下前n个子元素就会依次摆放在对应的列下,后面的元素另起一行,依次类推(跟flex-wrap
有点像)。当然,可以改变这种默认的处理方式,后面再提。
grid-template-rows
用于确定网格的行数
一般情况下不需要显示声明行数~
grid-auto-rows
用于指定隐使行高
grid-auto-rows: 200px;
grid-auto-rows: minmax(100px, auto);
默认情况下行的高度由内容撑开
如果显示使用
grid-template-rows
声明了行高,则grid-auto-rows
的高度会被忽略minmax
函数用于指定行的最小高度和最大高度,类似于min-height
和max-height
的展示效果
网格间距
grid-column-gap
,用于指定两列之间的间距grid-row-gap
,用于指定两行之间的间距grid-gap
,上面两个属性的简写,第一个值是行间距,第二个值是列间距
需要注意的是间距与列宽以及容器自身宽度之间,可能发生过分受限的情形。这种情况下,可能会发生列超出容器范围的情形
定位
基于网格线的定位
上面通过指定列和行来绘制网格,每一列和每一行交叉绘制网格单元,他们的边界线即为网格线。网格线的编号顺序取决于文章的书写模式,在从左至右书写的语言中,编号为 1 的网格线位于最左边。
水平方向的网格线即为行线,竖直方向的网格线即为列线。相关语法文档里面说的很详细
坐标
有了网格线的概念后,我们就可以确定每一个网格单元的坐标。而对于网格容器内的子元素来说,我们也可以直接指定他们需要占据的的网格单元
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 3;
grid-column-start
,指定子元素的起始列grid-column-end
,指定子元素的终止列grid-row-start
,指定子元素的起始行grid-row-end
,指定子元素的终止行
可见网格区域只能是一个矩形框。如果终止行超过现有行数,则会隐式创建新行。
只有网格容器的第一代子元素会受网格布局的限制。当然,如果声明子元素也为display:grid
,则可以实现嵌套的网格布局,需要注意的是网格属性不具备继承特性。
简写
CSS提供了指定行列的简写方式
grid-column: 1/3;
grid-row: 1/2;
grid-column: start-column/end-column
,其中start-column
表示起始列,end-column
表示终止列grid-row: start-row/end-row
除了手动指定指标之外,也可以通过关键字span
来表明占据的网格数量
grid-column: 1/ span 2
表示起始列线为1,占据2个网格单元(即终止列线为3)
此外还可以使用grid-area
这个终极大招
grid-area: 1 / 1 / 4 / 2;
在从左往右的书写顺序语言中,上面从左往右依次对应grid-row-start
,grid-column-start
,grid-row-end
和grid-column-end
省略
可以省略grid-column-end
和grid-row-end
,默认情况下会分配单行或单列。
这意味着在简写方式中,可以省略分母
grid-coulmn: 2
表示grid-column-end:2
。
反向计数
可以从行和块结束线开始反方向计数,但是我感觉这种操作不是很直观~
层级
多个网格项目可以占据同一个网格单元,此时,默认后面元素覆盖前面元素的。可以通过z-index
指定层级
网格模板
讲道理,我第一次看到这里的时候,真的是被震惊到了:CSS还能这么玩儿!!
直接拿文档的demo来了
<style>
.header {
grid-area: hd;
}
.footer {
grid-area: ft;
}
.content {
grid-area: main;
}
.sidebar {
grid-area: sd;
}
.wrapper {
display: grid;
grid-template-columns: 1fr 2fr;
grid-auto-rows: minmax(100px, auto);
grid-template-areas:
"hd hd"
"sd main"
"ft ft";
}
.wrapper > div{
margin: 10px;
background-color: red
}
</style>
<body>
<div class="wrapper">
<div class="header">Header</div>
<div class="sidebar">Sidebar</div>
<div class="content">Content</div>
<div class="footer">Footer</div>
</div>
</body>
这段代码实现了一个常见的布局。在前面我们了解了grid-area
的用法,是基于网格线定位的简写方式。然而这里我们看到了它的另外一种用法:命名网格区域
注意grid-template-areas
语法,通过命名完成了一个字符串模板,实际上渲染出来的页面,就是该模板的布局样式~这才是正儿八经的可视化布局啊!!
响应式布局
看到这个使用方式,想到的第一件事情就是响应式布局的实现。
通过媒介查询和grid-template-areas
,我们可以很轻松地完成响应式布局,因为只需要改变模板,浏览器就会重新渲染。这跟Bootstrap中的栅格系统不同,栅格系统实现响应式布局的原理是
每一个列的宽度由百分比控制,然后在不同屏幕宽度下小屏幕的样式类被高屏幕的样式类覆盖。
然而grid-template-areas
给予我们更大的灵活度,样式也更加简洁~
简写
命名网格方式提供了两个简写方式
grid-template:
"hd hd" minmax(100px, auto)
"sd main" minmax(100px, auto)
"ft ft" minmax(100px, auto) / 1fr 2fr
分别对应grid-template-areas
网格模板,grid-auto-rows
单行高度和grid-template-columns
列。
此外还有grid
的简写方式,可以应用跟grid-template
相同的属性值。使用缩写容易让人困惑,这里还是要谨慎一点。
注意事项
网格模板中,命名的区域只能围城矩形区域,可以使用.
来表示留白
网格线命名
在用 grid-template-rows
和 grid-template-columns
属性定义网格时,可以为网格中的部分或全部网格线命名
grid-template-columns: [col-1-start] 1fr [col-1-end] 1fr 1fr
上面为将第一根垂直网格线命名为col-1-start
,将第二根网格线命名为col-1-end
。
网格线的名称与其序号具有相同的作用,即可以在grid-column
等属性中使用。与数字序号相比,使用网格线的命名更加直观和语义化,且不会根据网格线数量轻易改变。
此外,甚至可以为同一根网格线取多个名字,名称间以空格分隔。
对齐
网格包含对齐特征,提供了方便的对齐方式,用于子元素在其网格区域内的对齐。
aligin-itmes
用于指定网格容器子元素的对齐方式
跟flex
的align-items
类似的作用,具体取值可参考这里
align-self
用于指定子元素覆盖其网格容器指定的对齐方式
跟flex
的align-self
类似的作用
小结
这里简单整理了CSS网格布局的相关用法,其中被网格模板布局给震惊到了。除此之外,还有默认布局规则、书写模式等内容没有去了解。
尽管近一段时间可能还不太敢尝试在项目中使用网格布局,不过了解相关的发展方向还是很有必要的。个人感觉,未来网格布局应该会一统江湖的哈哈~
你要请我喝一杯奶茶?
版权声明:自由转载-非商用-保持署名和原文链接。
本站文章均为本人原创,参考文章我都会在文中进行声明,也请您转载时附上署名。