在Web Page Layout 的演进历史中,我们从刚开始的 table 到 float、position、inline-block,再到css3的盒子模型Flexbox。现在工作中已经经常用到Flexbox。
总的来说 Web 布局经历了以下四个阶段:
Grid Layout 是一种基于二维网格的布局系统,旨在完全改变我们设计基于网格的用户界面的方式,弥补网页开发在二维布局能力上的缺陷。
与flex分为伸缩容器和伸缩项目类似,grid也分为网格容器和网格项目。
今年3月份之后,各大主流浏览器都发布了对CSS Grid的支持,还是很有必要去学习下的:
一个元素添加 display: grid 属性后,它就成为了一个网格容器啦。
网格容器中的子元素就叫网格项目
<div class="grid-container">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
注意:column, float, clear, 和 vertical-align 元素对网格容器不起作用
通过一组值来定义网格的行和列,值得大小代表轨道的大小
<track-size>
:可以是一个长度值(px em等)、百分比或者是网格中自由空间的一部分(fr为单位,类似于Flexbox里面的 flex-basis 的值)<line-name>
:你选择的任意名称.container {
grid-template-columns: <track-size> ... | <line-name> <track-size> ... | subgrid;
grid-template-rows: <track-size> ... | <line-name> <track-size> ... | subgrid;
}
.container{
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end]; grid-template-rows: [row1-start] 25% [row1-end] 100% [third-line] auto [last-line];
}
请注意,一条网格线可以具有有多个名称。例如,这里的第二行将有两个名字: row1-end 和 row2-start:
.container{
grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end]; }
如果你的定义中包含重复的部分,你可以使用 repeat() 表示法进行精简:
.container{ grid-template-columns: repeat(3, 20px [col-start]) 5%; }
等效于:
.container{ grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%; }
fr 单位允许你将一个轨道大小设置为网格容器内自由空间的一小部分。如下所示,每个网格项就会占据网格容器宽度的三分之一:
.container{
grid-template-columns: 1fr 1fr 1fr;
}
<grid-ara-name>
:网格区域名称将这个网格容器划分成几个区域,从而组成一个网格模板,这几个区域有各自的名称,子项目通过 grid-area 属性来占有相应的区域。
<div class="grid-container">
<div class="grid-item item1">header</div>
<div class="grid-item item2">main</div>
<div class="grid-item item3">slidebar</div>
<div class="grid-item item4">footer</div>
</div>
<style>
.grid-container {
display: grid;
width: 600px;
height: 600px;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto;
grid-template-areas: "header header header header"
"main main . slidebar"
"footer footer footer footer"
}
.grid-item {
font-size: 20px;
color: #fff;
}
.item1 {
background: #05EDB7;
grid-area: header;
}
.item2 {
grid-area: main;
background: #4C8CF5;
}
.item3 {
grid-area: slidebar;
background: #F1F962;
}
.item4 {
grid-area: footer;
background: #F97F78;
}
</style>
另外这里用 . 表示一个空的单元格。
注意: 这里命名的网各区域的同时,区域两边的网格线会自动得到命名,比如上面的:header-start header-end
这两个属性是用来设置间隙(两者之间,不包括边缘)的大小,也就是轨道与轨道之间网格线的大小,可以理解为行/列之间设置的margin大小。
<gap-size>
:一个长度值.grid-container {
display: grid;
width: 600px;
height: 600px;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-row-gap: 20px;
grid-column-gap: 10px;
}
.grid-item {
background: #05EDB7;
font-size: 20px;
color: #fff;
}
grid-gap 是 grid-row-gap 和 grid-column-gap 的复合属性,注意先是行再是列:
grid-gap: 20px 10px;// 等价于:grid-row-gap: 20px;
grid-column-gap: 10px;
如果只有一个值,就是两者相同。
定义所有网格项相对于列轴在水平方向上的对齐方式
与 justify-items相对应的,网格项目在所在的行轨道上的对齐方式,属性值同样和列对齐是一样的:
定义网格列宽的时候,当你使用px之类的非响应式长度单位,并且网格大小小于网格容器的时候,这种情况下可以设置网格之间的对齐方式。justify-content 就是设置网格在y轴上的对齐方式,就像下面的例子:
.grid-container {
display: grid;
width: 400px;
height: 400px;
border: 1px solid #F97F78;
grid-template-columns: 80px 120px 80px;
grid-template-rows: auto;
grid-gap: 10px;
/*justify-content: center;*/
}
.grid-item {
background: #05EDB7;
font-size: 20px;
color: #fff;
}
看下它的属性值:
和上面的 justify-content 道理是一样的,不过 align-content是网格在垂直方向上的对齐方式
指定任何自动生成的网格轨道(隐式网格)的大小。当显示定位行与列(使用 grid-template-columns/grid-template-rows属性)时候,如果网格项目超出了网格的定义范围,那么就会创建隐式网格。
.grid-container {
display: grid;
width: 400px;
height: 400px;
border: 1px solid #F97F78;
grid-template-columns: 100px 100px;
grid-template-rows: 100px 100px;
grid-auto-columns: 1fr;
}
.item1 {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item2 {
grid-column: 2 / 3;
grid-row: 2 / 3;
}
.item3 {
grid-column: 5 / 6;
grid-row: 2 / 3;
}
因为引用了不存在的网格线,所以会自动创建隐式轨道来填补空白。这时候就可以使用 grid-auto-columns 和 grid-auto-rows 来设置隐式轨道的宽度。
当我们没有显示地在网格中放置网格项,这时候自动布局会自动帮助我们排列网格项,使用grid-auto-flow 可以更改自动排列的方式。
-row:自动布局会将没有定义位置的网格项填充每一行,必要时添加新行(默认)
.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;
}
如果我们将grid-auto-flow属性设置为 column,item-b, item-c 和 item-d 就会沿列轴进行布局。
这是一个复合属性,可以设置 grid-template-rows 、 grid-template-columns 、 grid-template-areas 、 grid-auto-rows +、grid-auto-columns 以及 grid-auto-flow
grid = grid-template-columns + grid-template-rows + grid-template-areas + grid-auto-rows + grid-auto-columns + grid-auto-flow
<grid-template-rows>/<grid-template-columns>
:将这两个属性的值设置指定值,其余的子属性值为初始值<grid-auto-flow>[<grid-auto-rows> [/<grid-auto-columns>]]
:这三个属性分别接受相同的值,如果省略了 grid-auto-columns 属性,它将设置为 grid-auto-rows 属性的值。如果两个都被忽略,那么都将设置为初始值。grid: 100px auto / 1fr auto 1fr;
// 等价于:
grid-template-rows: 100px auto;
grid-template-columns: 1fr auto 1fr;
grid-template-areas: none;
grid: column 1fr / auto;
// 等价于:
grid-auto-flow: column;
grid-auto-rows: 1fr;
grid-auto-columns: auto;
// 一次设置 `grid-template-areas` `grid-template-rows` `grid-template-columns`
grid: [row1-start] "header header header" 1fr [row1-end]
[row2-start] "footer footer footer" 200px [row2-end]
/ auto 50px auto;// 等价于:grid-template-areas: "header header header"
"footer footer footer";
grid-template-rows: [row1-start] 1fr [row1-end row2-start] 200px [row2-end];
grid-template-columns: auto 50px auto;
用网格线来包围出一片区域来定义网格项在网格容器中的位置
<line>
:可以是一个数字来引用相应编号的网格线,或者使用名称引用相应命名的网格线。<number>
:网格项区域所跨的网格轨道的数量<name>
:网格项包含指定名称网格项的网格线之前的网格轨道(这个我感觉和直接使用<name>
是一样的啊,没什么区别)如果没有声明 grid-column-end/grid-row-end,默认情况下网格项的跨度是 1。 网格项可以互相重叠,使用 z-index 设置层级顺序
.item1 {
background: red;
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 2;
}
.item2 {
background: blue;
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 2;
}
grid-column = grid-column-start + grid-column-end
grid-row = grid-row-start + grid-row-end
<start-line> / <end-line>
:可以是跨度或者网格线同样的,如果只用一个值,也就是没有声明结束的网格线,默认的轨道跨度为 1
网格容器通过属性 grid-template-areas 定义网格模板,每个区域定义自己的名称,然后网格项通过 属性grid-area 来选择自己区域,就像填色一样。
如果网格容器没有定义模板,那么这个属性相当于 grid-column和grid-row的和,也就是由四个值组成
<name>
:区域的名称<row-start>/<column-start>/<row-end>/<column-end>
:四个值组成,可以是数字或者名称,要注意顺序.item1 {
grid-area: 2 / 1 / 2 / 3
}
定义某个网格项相对于所在的列轴在水平方向上的对齐方式(可以定义某个网格项不同于使用 justify-items 的对齐方式)
.item-a{
justify-self: start;
}
.item-a{
justify-self: end;
}
定义 某个网格项 相对于行轴在垂直方向上的对齐方式(可以定义某个网格项不同于 使用 align-items 的对齐方式)
这个与justify-self属性相同,不过是在垂直方向上。
参考:
https://www.w3cplus.com/css3/a-complete-guide-css-grid-layout.html https://www.cnblogs.com/xiaohuochai/p/7083153.html http://blog.csdn.net/mr_wuch/article/details/73639592