grid 网格布局

1. 什么是 grid 网格布局

Grid 布局即网格布局,是一个二维的布局方式,由纵横相交的两组网格线形成的框架性布局结构,能够同时处理行与列。

擅长将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系,这与之前讲到的 flex 一维布局不相同。

设置 display: grid 或 display: inline-grid 的元素就是网格布局容器,这样就能触发浏览器渲染引擎的网格布局算法。

<div class="container">
    <div class="item item-1">
        <p class="sub-item"></p>
    </div>
    <div class="item item-2"></div>
    <div class="item item-3"></div>
</div>

上述代码实例中,.container 元素就是网格布局容器,.item 元素就是网格的项目,由于网格元素只能是容器的顶层子元素,所以 <p> 元素并不是网格元素。

2. 容器属性

  • display 属性:在元素上设置 display: grid 或 display: inline-grid 来创建一个网格容器。
  • grid-template-columns / grid-template-rows:设置列宽和行高。
.wrapper {
  display: grid;
  /* 声明了三列,宽度分别为 200px 200px 200px */
  grid-template-columns: 200px 200px 200px;
  grid-gap: 5px;
  /* 声明了两行,行高分别为 50px 50px */
  grid-template-rows: 50px 50px;
}

上述重复值可通过 repeat() 函数简写:

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 200px);
  grid-gap: 5px;
  grid-template-rows: repeat(2, 50px);
}
  • grid-row-gap / grid-column-gap / grid-gap:分别设置行间距、列间距以及两者的简写。
grid-row-gap: 10px;    /* 行间距 */
grid-column-gap: 20px; /* 列间距 */
grid-gap: 10px 20px;   /* 简写 */
  • grid-template-areas:用于定义区域,一个区域由一个或者多个单元格组成。
.container {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 100px 100px 100px;
  grid-template-areas: 'a b c'
                       'd e f'
                       'g h i';
}

上面代码先划分出 9 个单元格,然后将其定名为 a 到 i 的九个区域。如果某些区域不需要利用,则使用"点"(.)表示。

多个单元格合并成一个区域的写法:

grid-template-areas: 'a a a'
                     'b b b'
                     'c c c';
  • justify-items / align-items / place-items:
    • justify-items 设置单元格内容的水平位置(左中右);
    • align-items 设置单元格的垂直位置(上中下);
    • place-items 是 align-items 和 justify-items 的合并简写形式。
.container {
  justify-items: start | end | center | stretch;
  align-items: start | end | center | stretch;
}
  • justify-content / align-content / place-content:
    • justify-content 是整个内容区域在容器里面的水平位置;
    • align-content 是整个内容区域的垂直位置。
.container {
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
  align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}

3. 项目属性

  • grid-area:指定项目放在哪一个区域。
.item-1 {
  grid-area: e;
}
  • justify-self / align-self:
    • justify-self 设置单元格内容的水平位置(左中右),跟 justify-items 的用法完全一致,但只作用于单个项目;
    • align-self 设置单元格内容的垂直位置(上中下),跟 align-items 的用法完全一致。
.item {
  justify-self: start | end | center | stretch;
  align-self: start | end | center | stretch;
}
  • grid-column-start / grid-column-end / grid-row-start / grid-row-end:指定网格项目所在的四个边框,分别定位在哪根网格线。
<style>
    #container {
        display: grid;
        grid-template-columns: 100px 100px 100px;
        grid-template-rows: 100px 100px 100px;
    }
    .item-1 {
        grid-column-start: 2;
        grid-column-end: 4;
    }
</style>
<div id="container">
    <div class="item item-1">1</div>
    <div class="item item-2">2</div>
    <div class="item item-3">3</div>
</div>

通过设置 grid-column 属性,指定 1 号项目的左边框是第二根垂直网格线,右边框是第四根垂直网格线。

补充:现代 grid 布局还有 grid-auto-flow(控制自动布局算法)、grid-auto-rows/grid-auto-columns(隐式网格大小)等高级属性,可以实现瀑布流、自动填充等复杂效果。