CSS布局新方案——Grid 网格布局
来源:互联网 发布:淘宝手机海报尺寸2017 编辑:程序博客网 时间:2024/05/17 06:41
CSS Grid 是一个基于二维网格布局的系统,虽然目前浏览器支持并不理想,但是今年3月份之后,各大主流浏览器都发布了对CSS Grid的支持,还是很有必要去学习下的
在Web Page Layout 的演进历史中,我们从刚开始的 table 到 float、position、inline-block,再到css3的盒子模型Flexbox。Flexbox已经可以帮助我们解决好多布局的烦恼,我在工作中会经常用到
虽然Flexbox可以起到一定的补救作用,但是它只可以实现简单的一维布局,并不适用于复杂的二维布局(实际上 Flexbox 和 Grid 可以一起结合使用起到最佳效果)。网格是 CSS 第一次专门创建的模块,用来解决我们之前在制作网站时使用hacks处理布局问题。
Grid 术语
网格容器(Grid Container)
这个类似于Flexbox里面的Flex容器
一个元素添加 display: grid
属性后,它就成为了一个网格容器
网格项目(Grid Item)
网格容器中的子元素就叫网格项目
<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>
这里的 div.grid-container
是网格容器,div.grid-item
是网格项目
网格线(Grid Line)
网格轨道(Grid Track)
网格单元格(Grid Cell)
网格区域(Grid Area)
容器属性
1. display
定义一个元素成为网格容器,并对其内容建立一个网格格式的上下文。
grid
:定义一个块级网格inline-grid
:定义一个内联级网格
注意: 定义为网格容器后,column
, float
, clear
, 和 vertical-align
元素对网格容器不起作用
2. grid-template-rows 和 grid-template-columns
通过一组值来定义网格的行和列,值得大小代表轨道的大小
属性值:
<track-size>
:可以是一个长度值(px em等)、百分比或者是网格中自由空间的一部分(fr为单位,类似于Flexbox里面的 flex-basis 的值)<line-name>
:你选择的任意名称subgrid
:如果你的网格容器本身就是一个网格项(即嵌套网格),你可以使用此属性指定行和列的大小继承于父元素而不是自身指定(一般很少会用)
.container{ grid-template-columns: <track-size> ...; grid-template-columns: <line-name> <track-size> ...; grid-template-columns: subgrid;}
示例:
<div class="grid-container"> <div class="grid-item item1">1</div> <div class="grid-item item2">2</div> <div class="grid-item item3">3</div> <div class="grid-item item4">4</div> <div class="grid-item item5">5</div> <div class="grid-item item6">6</div> <div class="grid-item item7">7</div> <div class="grid-item item8">8</div></div>
<style> .grid-container { display: grid; width: 600px; height: 600px; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 25% 250px auto; } .grid-item { background: #05EDB7; } .grid-item { border: 1px solid #4B8BF5; font-size: 20px; color: #fff; }</style>
可以看到,网格容器被 grid-template-columns
grid-template-rows
分成了三列三行,列通过 1fr 1fr 1fr
分成了等宽的三份,项目默认会充满单元格。
这里如果 <track-size>
有连续重复的值,可以使用 repeat()
:
grid-template-columns: 1fr 1fr 1fr;
等价于:
grid-template-columns: repeat(3, 1fr);
3. grid-template-areas
属性值:
<grid-ara-name>
:网格区域名称.
:空单元格none
:无网格区域被定义
将这个网格容器划分成几个区域,从而组成一个网格模板,这几个区域有各自的名称,子项目通过 grid-area
属性来占有相应的区域。这个我觉得和vue里面的slot具名插槽有点类似,下面看一个例子:
<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>
你可以看到是不是和slot有些类似
另外这里用 .
表示一个空的单元格。
注意: 这里命名的网各区域的同时,区域两边的网格线会自动得到命名,比如上面的:header-start
header-end
4. grid-column-gap 和 grid-row-gap
从gap的意思就可以看出来,这两个属性是用来设置间隙(两者之间,不包括边缘)的大小,也就是轨道与轨道之间网格线的大小,可以理解为行/列之间设置的margin大小。
属性值:
<gap-size>
:一个长度值
示例:
<div class="grid-container"> <div class="grid-item item1">1</div> <div class="grid-item item2">2</div> <div class="grid-item item3">3</div> <div class="grid-item item4">4</div> <div class="grid-item item5">5</div> <div class="grid-item item6">6</div> <div class="grid-item item7">7</div> <div class="grid-item item8">8</div> <div class="grid-item item9">9</div></div>
.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;}
5. grid-gap
grid-gap
是 grid-row-gap
和 grid-column-gap
的复合属性,注意先是行再是列:
grid-gap: 20px 10px;// 等价于:grid-row-gap: 20px;grid-column-gap: 10px;
如果只有一个值,就是两者相同。
6. justify-items
定义 所有网格项 相对于 列轴 在水平方向上的对齐方式
属性值:
start
:项目与网格轨道的左端对齐end
:项目与网格轨道的右端对齐center
:在项目所在轨道居中对齐stretch
:项目宽度占据整个单元格区域(默认值,前提是项目没有设置宽度)
示例:
以 justify-items: center
为例,这里一些项目设置了宽度,可见没有设置宽度的项目(3和7)宽度没有充满单元格:
7. align-items
与 justify-items
相对应的,网格项目在所在的 行轨道 上的对齐方式,属性值同样和列对齐是一样的:
start
:项目与行轨道顶端对齐end
:项目与行轨道底端对齐center
:项目与行轨道居中=对齐stretch
:项目高度占据整个单元格区域(默认值,前提是项目没有设置高度,从上面的例子可以看出)
8. justify-content
定义网格列宽的时候,当你使用 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;}
这里通过 grid-template-columns: 80px 120px 80px;
定义了 80px
、120px
、80px
三列的网格,但是网格容器是600px,现在就可以设置网格之间的对齐方式,初始的时候是下面的样子,可以看到有一部分空白:
现在来看下 justify-content 的属性值:
start
:网格在网格容器中左对齐
end
:网格在网格容器中右对齐
center
:网格在网格容器中居中对齐
stretch
:调整网格的大小,使其宽度填充整个网格容器(这个我设置了但还是没什么作用,和start是一样的效果,不知道是不是理解错了)space-around
:和Flexbox里面的是一样的道理,设置网格左右两边的边距相等
space-between
:和Flexbox里面的是一样的道理,两端对齐,也就是网格与网格之间的距离相等,左右边缘的网格贴边
space-evenly
:正如 evenly 的意思一样,平均分配空白区域,使网格之间以及边缘的网格到边缘的距离都相等。为了模拟这个,先把grid-gap
值设为0,可以从下图看到空白被等分了
9. align-content
这个和上面的 justify-content
道理是一样的,不过 align-content
是网格在 垂直 方向上的对齐方式自动生成,就不做介绍了
10. grid-auto-columns 和 grid-auto-rows
指定任何自动生成的网格轨道(隐式网格)的大小。当显示定位行与列(使用 grid-template-columns
/grid-template-rows
属性)时候,如果网格项目超出了网格的定义范围,那么就会创建隐式网格。
属性值:
<track-size>
:可以是长度、百分比、或网格自由空间的一部分(以fr
为单位)
示例:
创建一个两列两行的网格
.grid-container { display: grid; width: 400px; height: 400px; border: 1px solid #F97F78; grid-template-columns: 100px 100px; grid-template-rows: 100px 100px;}
定义两个网格项:
.item1 { grid-column: 1 / 2; grid-row: 2 / 3;}.item2 { grid-column: 5 / 6; grid-row: 2 / 3;}
两列两行的网格,网格线编号是从1到3,而网格项item3定义起始列线5到终止列线6之间的区域,这超出了定义范围,如图所示:
因为引用了不存在的网格线,所以会自动创建隐式轨道来填补空白。这时候就可以使用 grid-auto-columns
和 grid-auto-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;}
11. grid-auto-flow
这个属性,当我们没有显示地在网格中放置网格项,这时候自动布局会自动帮助我们排列网格项,使用grid-auto-flow
可以更改自动排列的方式。
属性值:
row
:自动布局会将没有定义位置的网格项填充每一行,必要时添加新行(默认)column
:自动布局会将没有定义位置的网格项填充每一列,必要时添加新列row dense/column dense
:如果按照row或者column排列的话出现空白,设置dense自动布局会试图填充空白
示例:
如图所示,定义一个5列5行的网格,这里并没有定义网格项的大小,可以看到,默认是填每一行,即 row
:
现在我们来调整 item7 的区域大小:
.item7 { grid-column: span 2; grid-row: span 2;}
如下图所示,其他的网格项会自动填充每一行:
如果 grid-auto-flow
的值改为 column
是同样的道理:
现在回到默认的 row
,再改变 item9 的大小:
.item9 { grid-column: span 2; grid-row: span 2;}
会变成下图所示的效果:
item9被换到了新的一行,这时候item8傍边以及item6下面会出现空白,看着很是别扭,这时候就需要用到 dense
:
.grid-container { display: grid; width: 400px; height: 400px; border: 1px solid #F97F78; grid-template-columns: repeat(5, 1fr); grid-template-rows: repeat(5, 1fr); grid-gap: 2px; grid-auto-flow: row dense;}
这里如果是按照行来排列的话 row
可以省略,因为默认是 row
;如果是按列来排列的,就需要写为:grid-auto-flow: column dense
。
12. grid
这是一个复合属性,可以设置 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
属性值:
none
:将所有的子属性设置为初始值subgrid
:将grid-template-rows
和grid-template-columns
的值设置为subgrid
(继承来自父元素的设置),其余子属性值为初始值<grid-template-rows>/<grid-template-columns>
:将这两个属性的值设置指定值,其余的子属性值为初始值<grid-auto-flow>[<grid-auto-rows> [/<grid-auto-columns>]]
:这三个属性分别接受相同的值,如果省略了grid-auto-columns
属性,它将设置为grid-auto-rows
属性的值。如果两个都被忽略,那么都将设置为初始值。
示例:
grid: 100px auto / repeat(3, 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;
网格项目的属性
1. grid-column-start/grid-column-end/grid-row-start/grid-row-end
用网格线来包围出一片区域来定义网格项在网格容器中的位置
属性值:
<line>
:可以是一个数字来引用对应编号的网格线,或者是你在定义grid-template-...
时候定义的网格线名称。span <number>
:网格项区域所跨的网格轨道的数量span <name>
:网格项包含指定名称网格项的网格线之前的网格轨道(这个我感觉和直接使用<name>
是一样的啊,没什么区别)auto
:自动定位
示例:
.grid-container { display: grid; width: 400px; height: 400px; border: 1px solid #F97F78; grid-template-columns: 1fr [col2-start] 1fr [col2-end col3-start] 1fr [col3-end col4-start] 1fr [col-end]; grid-template-rows: 1fr [row2-start] 1fr [row2-end col3-start] 1fr [row3-end row4-start] 1fr [col-end]; justify-content: stretch;}.grid-item { background: #05EDB7; font-size: 20px; color: #fff;}.item1 { grid-column-start: 1; grid-column-end: span col4-start; grid-row-start: 1; grid-row-end: span 3;}
如果没有声明
grid-column-end
/grid-row-end
,默认情况下网格项的跨度是 1。
网格项可以互相重叠,使用z-index
设置层级顺序
2. grid-column/grid-row
grid-column
= grid-column-start
+ grid-column-end
grid-row
= grid-row-start
+ grid-row-end
属性值:
<start-line> / <end-line>
:可以是跨度或者网格线
示例:
.grid-container { display: grid; width: 400px; height: 400px; border: 1px solid #F97F78; grid-template-columns: 1fr [col2-start] 1fr [col2-end col3-start] 1fr [col3-end col4-start] 1fr [col-end]; grid-template-rows: 1fr [row2-start] 1fr [row2-end col3-start] 1fr [row3-end row4-start] 1fr [col-end]; justify-content: stretch;}.grid-item { background: #05EDB7; font-size: 20px; color: #fff;}.item1 { grid-column: 1 / col4-start; grid-row: 1 / span 3;}
同样的,如果只用一个值,也就是没有声明结束的网格线,默认的轨道跨度为 1
3. grid-area
这个在上面已经提到过,网格容器通过属性 grid-template-areas
定义网格模板,每个区域定义自己的名称,然后网格项通过 属性grid-area
来选择自己区域,就像填色一样。
如果网格容器没有定义模板,那么这个属性相当于 grid-column
和grid-row
的和,也就是由四个值组成
属性值:
<name>
:区域的名称<row-start>
/<column-start>
/<row-end>
/<column-end>
:四个值组成,可以是数字或者名称,要注意顺序
示例:
.grid-container { display: grid; width: 400px; height: 400px; border: 1px solid #F97F78; grid-template-columns: 1fr [col2-start] 1fr [col2-end col3-start] 1fr [col3-end col4-start] 1fr [col-end]; grid-template-rows: 1fr [row2-start] 1fr [row2-end col3-start] 1fr [row3-end row4-start] 1fr [col-end]; justify-content: stretch;}.grid-item { background: #05EDB7; font-size: 20px; color: #fff;}.item1 { grid-area: 2 / 1 / row4-start / 3}
4. justify-self
定义 某个网格项 相对于所在的列轴在水平方向上的对齐方式(可以定义某个网格项不同于 使用 justify-items
的对齐方式)
属性值:
start
:网格项在所在网格区域左对齐end
:网格项在所在网格区域右对齐center
:居中对齐stretch
:网格项宽度占据整个网格区域(默认,前提是项目没有设置宽高)
示例:
.grid-container { display: grid; width: 400px; height: 400px; border: 1px solid #F97F78; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); grid-gap: 5px; justify-items: start;}.grid-item { width: 50px; height: 50px; background: #05EDB7; font-size: 20px; color: #fff;}
- start
.item1 { justify-self: start;}
- end
.item1 { justify-self: end;}
- center
.item1 { justify-self: center;}
5. align-self
定义 某个网格项 相对于行轴在垂直方向上的对齐方式(可以定义某个网格项不同于 使用 align-items
的对齐方式)
引用文章
CSS Grid布局这样玩
CSS Grid布局指南
- CSS布局新方案——Grid 网格布局
- CSS Grid 网格布局
- CSS Grid布局:网格区域
- CSS Grid布局:什么是网格布局
- CSS Grid布局:什么是网格布局
- CSS Grid布局:网格单元格布局
- CSS Grid布局:网格单元格布局
- CSS网格布局(Grid)完全教程
- css grid布局教程之什么是网格布局?
- CSS Grid布局教程之网格单元格布局
- CSS Grid布局:图解网格布局中术语之一
- CSS Grid布局:图解网格布局中术语三
- ui-grid 网格布局
- ie10 grid 网格布局
- CSS Grid布局:独立源与网格的层叠顺序
- GridLayout—网格布局
- 网页布局--CSS网格布局
- css网格布局
- 信公众号支付JSAPI通过ajax获取支付参数,报错:2支付缺少参数:appId。
- 非交互环境下admin权限转system权限小脚本
- Kotlin基础 4
- 浅谈HashMap
- AngularJs1学习笔记:指令
- CSS布局新方案——Grid 网格布局
- Elasticsearch 5.4.1 windows 10 测试服务搭建
- git命令大全
- 巧用Android多进程,微信,微博等主流App都在用
- popupwindow不显示问题
- 机器学习之-使用FP-growth算法来高效发现频繁项集-具体怎么实现及应用
- Vue项目一键远程发布(upload to remote)全流程配置
- codeforces 281A(Word Capitalization) Java
- coding中那些不得不说的愚蠢的mistake(1)