Grid布局学习

学习Grid布局中的概念与属性

由于提案尚处于CR阶段,规范中的内容随时可能会发生变化

何为Grid布局

  • 一种二维的基于网格(或栅格)的布局方式
  • 该提案处于候选推荐(CR)阶段
  • 浏览器的支持情况如下:

与Flex布局相比

与Flex布局的共同点是元素均存放在一个父级容器内,尺寸与位置受容器影响。

最核心的区别是Flex布局使用单坐标轴的布局系统,而Grid布局中使用二维布局,使元素可以在二个维度上进行排列,如下图

  • Flex Layout
  • Grid Layout

特性

  • 自上而下的布局(划分网格区域,决定单元内容)
  • 可设置每个单元间隔距离
  • 具有自适应尺寸fr,fr取自fraction的前两个字母
  • 容器中的元素可以跨度扩展、覆盖与折叠

调试工具

目前最好的Grid布局调试工具应该是Firefox Nightly中的这个网格调试的辅助工具,可以显示网格线、间隔与网格单元,具体效果如下图所示。

概念

容器 - Container

将元素的display属性为grid即可定义一个网格容器

下面的代码中,container就是一个网格容器

1
2
3
4
5
<div class="container">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>

容器内部会构建一个网格格式化上下文,类似BFC的构建,不过网格布局与块布局不同的是:

  1. 浮动不会侵入进网格容器
  2. 容器外边距不会与内容外边距发生折叠

网格容器与块容器不一样,一些属性在网格容器上可能会不起作用:

  1. 多列布局中的column-*属性对网格容器不起作用
  2. floatclear属性对网格项目不起作用,
  3. vertical-align属性对网格项目不起作用
  4. 网格容器不具有::first-line::first-letter伪元素

项目 - Item

网格项目指的是网格容器的子元素

下面的代码中,item就是网格项目,而sub-item不是

1
2
3
4
5
6
7
<div class="container">
<div class="item"></div>
<div class="item">
<p class="sub-item"></p>
</div>
<div class="item"></div>
</div>

线条 - Line

横向与纵向的分割线条构成了网格

下图的黄线就是一条纵向网格线

轨道 - Track

网格轨道指的是两条平行的网格线之间的空间

下图的黄色区域是第二条和第三条横向网格线之间的轨道

网格单元 - Cell

网格单元指的是一对相邻横向线条与一对相邻纵向线条所围成的区域,是网格布局中的最小单元

区域 - Area

网格区域是用来布局多个网格项目的逻辑区域,可以由一个或多个网格单元组成

下图的黄色区域就是由横向网格线1和3与纵向网格线1和3所围成的区域

属性

容器属性

通过将display属性设为gridinline-grid分别创建一个块级或行内的网格容器

显式网格定义属性

通过下面这些属性可以定义固定数量的线条与轨道,这种手动定义的网格被称为显式网格(explicit grid)

  1. grid-template-columns / grid-template-rows
    以空格分割的列表设置网格的行与列,值为轨道的尺寸,单位可以是px(或em,rem),auto与fr等

    1
    2
    3
    4
    .container {
    grid-template-columns: 40px 50px auto 50px 40px;
    grid-template-rows: 25% 100px auto;
    }


    除此之外可以使用repeat()函数简化代码,下面两种定义方法效果相同

    1
    2
    3
    4
    5
    6
    .container {
    grid-template-columns: 100px 100px 100px 100px;
    }
    .container {
    grid-template-columns: repeat(4, 100px);
    }


    其中repeat的第一个参数为整数时表示个数,也可取auto-fillauto-fit进行自动填充
    auto-fill会取值为网格所能容纳的最大数量

    1
    2
    3
    4
    5
    .container {
    display: grid;
    grid-template-columns: repeat(auto-fill, 100px);
    grid-gap: 20px;
    }


    auto-fit的效果与auto-fill看起来一样,区别在于,若剩余的空间均为空网格时,会发生网格折叠

    1
    2
    3
    4
    5
    .container {
    display: grid;
    grid-template-columns: repeat(auto-fit, 100px);
    grid-gap: 20px;
    }


    可以看到右侧的列轨道6到11都折叠在了一起

  2. grid-template-areas
    通过使用grid-area属性(项目属性)指定的名称来定义网格中模板所占的区域

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    .item-a {
    grid-area: header;
    }
    .item-b {
    grid-area: main;
    }
    .item-c {
    grid-area: sidebar;
    }
    .item-d {
    grid-area: footer;
    }
    .container {
    grid-template-columns: 50px 50px 50px 50px;
    grid-template-rows: auto;
    grid-template-areas:
    "header header header header"
    "main main . sidebar"
    "footer footer footer footer";
    }

隐式网格定义属性

若有网格项目的区域超出了网格范围,则网格容器会自动添加网格线来生成网格轨道,这些网格线与显式网格构成了隐式网格(implicit grid)

在显式定义的网格范围之外的网格会应用隐式网格定义的属性值

通常在两种情况下会产生超出显式定义网格区域外的网格:

  • 一种是项目数量超过了显式定义网格的个数
  • 另一种是手动将项目放置在了一个指定的显式范围外的网格区域中
  1. grid-auto-columns / grid-auto-rows
    看下面这个例子

    1
    2
    3
    4
    5
    6
    7
    .container {
    display: grid;
    grid-template-columns: repeat(auto-fill, 100px);
    grid-template-rows: 100px;
    grid-auto-rows: 60px;
    grid-gap: 20px;
    }


    可以看出,由于显式只定义了一个行轨道,因此第二个行轨道尺寸应用的是grid-auto-rows的60px,grid-auto-columns属性的作用类似

  2. grid-auto-flow
    这个属性用来设置自动排列算法的工作方式,默认值为row,依次按行放置项目,也可设置为columndense

    看下面这个例子,注意item-b,c,d的位置
    row

    1
    2
    3
    4
    5
    6
    .container {
    display: grid;
    grid-template-columns: 60px 60px 60px 60px 60px;
    grid-template-rows: 30px 30px;
    grid-auto-flow: row;
    }


    column

    1
    2
    3
    4
    5
    6
    .container {
    display: grid;
    grid-template-columns: 60px 60px 60px 60px 60px;
    grid-template-rows: 30px 30px;
    grid-auto-flow: column;
    }


    dense会使自动排列算法使用一种紧凑的方案,会将尺寸较小的项目填充进较前的剩余空白空间中,这也许会导致项目不按顺序出现,可以看看这个例子,比较直观

项目属性

  1. grid-column-start / grid-column-end / grid-row-start / grid-row-end
    这几个属性用来设置项目横向与纵向的起始与终止网格线,取值可以为整数、线条名称、[span 整数]、[span 线条名称],用来指定该项目的占用区域

    1
    2
    3
    4
    5
    6
    .item {
    grid-column-start: 2;
    grid-column-end: five;
    grid-row-start: row1-start;
    grid-row-end: 3;
    }


    关于项目的覆盖:在设置项目所占区域时有可能发生覆盖,使用z-index可以设置它们的层级影响覆盖效果,如下例子,grid-columngrid-row为简写形式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    .item-1 {
    background-color: pink;
    grid-column: 2 / 5;
    grid-row: 1 / 2;
    z-index: 2;
    }
    .item-2 {
    background-color: red;
    grid-column: 3 / 4;
    grid-row: 1 / 3;
    z-index: 3;
    }
    .item-3 {
    background-color: peachpuff;
    grid-column: 4 / 5;
    grid-row: 1 / 3;
    z-index: 1;
    }


    可以看出,三个网格项目发生了覆盖现象,并且覆盖的具体效果是来源于z-index的值

  2. grid-area
    grid-area属性可以设置两种值:名称或者一组网格线
    设置名称后,可以在容器的grid-template-areas属性中使用设置它所占用的网格

    1
    2
    3
    .item {
    grid-area: header
    }

    也可以设为一组网格线,最多为四个值,分别对应grid-row-start / grid-column-start / grid-row-end / grid-column-end,若未定义则为auto

    1
    2
    3
    .item {
    grid-area: 1 / col4-start / last-line / 6
    }

  3. justify-self / align-self
    设置项目中内容的对齐方式,justify-self设置横轴上的对齐方式,align-self设置纵轴上的对齐方式

沟槽属性

用来设置网格单元之间的距离,也就是网格线的宽度

  1. grid-column-gap / grid-row-gap

    1
    2
    3
    4
    5
    6
    .container {
    grid-template-columns: 100px 50px 100px;
    grid-template-rows: 80px auto 80px;
    grid-column-gap: 10px;
    grid-row-gap: 15px;
    }

  2. grid-gap
    grid-row-gapgrid-column-gap的简写形式,上面的例子就可以写成
    1
    2
    3
    4
    .container {
    ...
    grid-gap: 15px 10px;
    }

弹性长度单位fr

使用fr会将轨道作为网格容器中自由空间中的一部分,而自由空间为除去非弹性项目的部分,看看下面这个例子

1
2
3
4
5
6
.container {
display: grid;
grid-template-columns: 1fr 1fr 50px 1fr;
grid-template-rows: 100px;
grid-gap: 20px;
}


可以看出第三个列轨道宽度为50px,其他三个轨道均分剩余的自由空间

资料

  1. CSS Grid Layout Module Level 1
  2. A Complete Guide to Grid
  3. The Difference Between Explicit and Implicit Grids
文章目录
  1. 1. 何为Grid布局
    1. 1.1. 与Flex布局相比
    2. 1.2. 特性
    3. 1.3. 调试工具
  2. 2. 概念
    1. 2.1. 容器 - Container
    2. 2.2. 项目 - Item
    3. 2.3. 线条 - Line
    4. 2.4. 轨道 - Track
    5. 2.5. 网格单元 - Cell
    6. 2.6. 区域 - Area
  3. 3. 属性
    1. 3.1. 容器属性
      1. 3.1.1. 显式网格定义属性
      2. 3.1.2. 隐式网格定义属性
    2. 3.2. 项目属性
    3. 3.3. 沟槽属性
    4. 3.4. 弹性长度单位fr
  4. 4. 资料
|