前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CSS布局新方案——Grid 网格布局

CSS布局新方案——Grid 网格布局

作者头像
江米小枣
发布2020-06-16 17:08:26
2.4K0
发布2020-06-16 17:08:26
举报
文章被收录于专栏:云前端云前端

在Web Page Layout 的演进历史中,我们从刚开始的 table 到 float、position、inline-block,再到css3的盒子模型Flexbox。现在工作中已经经常用到Flexbox。

总的来说 Web 布局经历了以下四个阶段:

  • 1、table表格布局,通过 Dreamweaver 拖拽表格或者手写 table 标签布局
  • 2、float浮动及position定位布局,借助元素元素盒模型本身的特性以及 float position 等属性等进行布局
  • 3、flex弹性盒模型布局,革命性的突破,解决传统布局方案上的三大痛点 排列方向、对齐方式,自适应尺寸。是目前最为成熟和强大的布局方案
  • 4、grid栅格布局,二维布局模块,具有强大的内容尺寸和定位能力,适合需要在两个维度上对齐内容的布局

Grid Layout 是一种基于二维网格的布局系统,旨在完全改变我们设计基于网格的用户界面的方式,弥补网页开发在二维布局能力上的缺陷。

与flex分为伸缩容器和伸缩项目类似,grid也分为网格容器和网格项目。

今年3月份之后,各大主流浏览器都发布了对CSS Grid的支持,还是很有必要去学习下的:

Grid 术语

网格容器(Grid Container)

一个元素添加 display: grid 属性后,它就成为了一个网格容器啦。

网格项目(Grid Item)

网格容器中的子元素就叫网格项目

代码语言:javascript
复制
<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>
网格线(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:如果你的网格容器本身就是一个网格项(即嵌套网格),你可以使用此属性指定行和列的大小继承于父元素而不是自身指定(一般很少会用)
代码语言:javascript
复制
.container {
   grid-template-columns: <track-size> ... | <line-name> <track-size> ... | subgrid;
   grid-template-rows: <track-size> ... | <line-name> <track-size> ... | subgrid;
}
代码语言:javascript
复制

   .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:

代码语言:javascript
复制
    .container{
       grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end]; }

如果你的定义中包含重复的部分,你可以使用 repeat() 表示法进行精简:

代码语言:javascript
复制
.container{ grid-template-columns: repeat(3, 20px [col-start]) 5%; }

等效于:

代码语言:javascript
复制
.container{ grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%; }

fr 单位允许你将一个轨道大小设置为网格容器内自由空间的一小部分。如下所示,每个网格项就会占据网格容器宽度的三分之一:

代码语言:javascript
复制
    .container{
       grid-template-columns: 1fr 1fr 1fr;
   }
3. grid-template-areas
  • <grid-ara-name>:网格区域名称
  • .:空单元格
  • none:无网格区域被定义

将这个网格容器划分成几个区域,从而组成一个网格模板,这几个区域有各自的名称,子项目通过 grid-area 属性来占有相应的区域。

代码语言:javascript
复制
<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>
代码语言:javascript
复制
<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

4. grid-column-gap 和 grid-row-gap

这两个属性是用来设置间隙(两者之间,不包括边缘)的大小,也就是轨道与轨道之间网格线的大小,可以理解为行/列之间设置的margin大小。

  • <gap-size>:一个长度值
代码语言:javascript
复制
.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 的复合属性,注意先是行再是列:

代码语言:javascript
复制
grid-gap: 20px 10px;// 等价于:grid-row-gap: 20px;
grid-column-gap: 10px;

如果只有一个值,就是两者相同。

6. justify-items

定义所有网格项相对于列轴在水平方向上的对齐方式

  • start :项目与网格轨道的左端对齐
  • end:项目与网格轨道的右端对齐
  • center:在项目所在轨道居中对齐
  • stretch:项目宽度占据整个单元格区域(默认值,前提是项目没有设置宽度)
7. align-items

与 justify-items相对应的,网格项目在所在的行轨道上的对齐方式,属性值同样和列对齐是一样的:

  • start:项目与行轨道顶端对齐
  • end:项目与行轨道底端对齐
  • center:项目与行轨道居中对齐
  • stretch:项目高度占据整个单元格区域(默认值,前提是项目没有设置高度,从上面的例子可以看出)
8. justify-content

定义网格列宽的时候,当你使用px之类的非响应式长度单位,并且网格大小小于网格容器的时候,这种情况下可以设置网格之间的对齐方式。justify-content 就是设置网格在y轴上的对齐方式,就像下面的例子:

代码语言:javascript
复制
.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;
}

看下它的属性值:

  • start:网格在网格容器中左对齐
  • end:网格在网格容器中右对齐
  • center:网格在网格容器中居中对齐
  • stretch:调整网格的大小,使其宽度填充整个网格容器
  • space-around:和Flexbox里面的是一样的道理,设置网格左右两边的边距相等
  • space-between:和Flexbox里面的是一样的道理,两端对齐,也就是网格与网格之间的距离相等,左右边缘的网格贴边
  • space-evenly:正如 evenly 的意思一样,平均分配空白区域,使网格之间以及边缘的网格到边缘的距离都相等。
9. align-content

和上面的 justify-content 道理是一样的,不过 align-content是网格在垂直方向上的对齐方式

10. grid-auto-columns 和 grid-auto-rows

指定任何自动生成的网格轨道(隐式网格)的大小。当显示定位行与列(使用 grid-template-columns/grid-template-rows属性)时候,如果网格项目超出了网格的定义范围,那么就会创建隐式网格。

  • track-size:可以是长度、百分比、或网格自由空间的一部分(以fr为单位)
代码语言:javascript
复制
.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;
}
代码语言:javascript
复制
.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 来设置隐式轨道的宽度。

11. grid-auto-flow

当我们没有显示地在网格中放置网格项,这时候自动布局会自动帮助我们排列网格项,使用grid-auto-flow 可以更改自动排列的方式。

-row:自动布局会将没有定义位置的网格项填充每一行,必要时添加新行(默认)

  • column:自动布局会将没有定义位置的网格项填充每一列,必要时添加新列
  • row dense/column dense:如果按照row或者column排列的话出现空白,设置dense自动布局会试图填充空白
代码语言:javascript
复制
.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 就会沿列轴进行布局。

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 属性的值。如果两个都被忽略,那么都将设置为初始值。
示例:
代码语言:javascript
复制
grid: 100px auto / 1fr auto 1fr;
// 等价于:
grid-template-rows: 100px auto;
grid-template-columns: 1fr auto 1fr;
grid-template-areas: none;
代码语言:javascript
复制
grid: column 1fr / auto;
// 等价于:
grid-auto-flow: column;
grid-auto-rows: 1fr;
grid-auto-columns: auto;
代码语言:javascript
复制
// 一次设置 `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>:可以是一个数字来引用相应编号的网格线,或者使用名称引用相应命名的网格线。
  • span <number>:网格项区域所跨的网格轨道的数量
  • span <name>:网格项包含指定名称网格项的网格线之前的网格轨道(这个我感觉和直接使用<name>是一样的啊,没什么区别)
  • auto:自动定位

如果没有声明 grid-column-end/grid-row-end,默认情况下网格项的跨度是 1。 网格项可以互相重叠,使用 z-index 设置层级顺序

代码语言:javascript
复制
.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;
}
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>:可以是跨度或者网格线

同样的,如果只用一个值,也就是没有声明结束的网格线,默认的轨道跨度为 1

3. grid-area

网格容器通过属性 grid-template-areas 定义网格模板,每个区域定义自己的名称,然后网格项通过 属性grid-area 来选择自己区域,就像填色一样。

如果网格容器没有定义模板,那么这个属性相当于 grid-column和grid-row的和,也就是由四个值组成

属性值:
  • <name>:区域的名称
  • <row-start>/<column-start>/<row-end>/<column-end>:四个值组成,可以是数字或者名称,要注意顺序
代码语言:javascript
复制
.item1 {
   grid-area: 2 / 1 / 2 / 3
}
4. justify-self

定义某个网格项相对于所在的列轴在水平方向上的对齐方式(可以定义某个网格项不同于使用 justify-items 的对齐方式)

属性值:
  • start:网格项在所在网格区域左对齐
  • end:网格项在所在网格区域右对齐
  • center :居中对齐
  • stretch:网格项宽度占据整个网格区域(默认,前提是项目没有设置宽高)
代码语言:javascript
复制
.item-a{
   justify-self: start;
}
代码语言:javascript
复制
.item-a{
   justify-self: end;
}
5. align-self

定义 某个网格项 相对于行轴在垂直方向上的对齐方式(可以定义某个网格项不同于 使用 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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-03-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云前端 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Grid 术语
    • 网格容器(Grid Container)
      • 网格项目(Grid Item)
        • 网格线(Grid Line)
          • 网格轨道(Grid Track)
            • 网格单元格(Grid Cell)
              • 网格区域(Grid Area)
              • 容器属性
                • 1. display
                  • 2. grid-template-rows 和 grid-template-columns
                    • 3. grid-template-areas
                      • 4. grid-column-gap 和 grid-row-gap
                        • 5. grid-gap
                          • 6. justify-items
                            • 7. align-items
                              • 8. justify-content
                                • 9. align-content
                                  • 10. grid-auto-columns 和 grid-auto-rows
                                    • 11. grid-auto-flow
                                      • 12. grid
                                      • 网格项目的属性
                                        • 1. grid-column-start/grid-column-end/grid-row-start/grid-row-end
                                          • 2. grid-column/grid-row
                                            • 3. grid-area
                                              • 4. justify-self
                                                • 5. align-self
                                                相关产品与服务
                                                容器服务
                                                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                                领券
                                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档