介绍一下grid网格布局

 ![](https://static.vue-js.com/4d73e3d0-9a94-11eb-85f6-6fac77c0c9b3.png)

## 一、是什么

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

擅长将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系

 ![](https://static.vue-js.com/59680a40-9a94-11eb-85f6-6fac77c0c9b3.png)

这与之前讲到的`flex`一维布局不相同

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

```js

<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`元素并不是网格元素

这里提一下,网格线概念,有助于下面对`grid-column`系列属性的理解

网格线,即划分网格的线,如下图所示:

 ![](https://static.vue-js.com/61be7080-9a94-11eb-ab90-d9ae814b240d.png)

上图是一个 2 x 3 的网格,共有3根水平网格线和4根垂直网格线

## 二、属性

同样,`Grid` 布局属性可以分为两大类:

- 容器属性,

- 项目属性

关于容器属性有如下:

### display 属性

文章开头讲到,在元素上设置`display:grid` 或 `display:inline-grid` 来创建一个网格容器

- display:grid 则该容器是一个块级元素

- display: inline-grid 则容器元素为行内元素

### grid-template-columns 属性,grid-template-rows 属性

`grid-template-columns` 属性设置列宽,`grid-template-rows` 属性设置行高

```css

.wrapper {

  display: grid;

  /*  声明了三列,宽度分别为 200px 200px 200px */

  grid-template-columns: 200px 200px 200px;

  grid-gap: 5px;

  /*  声明了两行,行高分别为 50px 50px  */

  grid-template-rows: 50px 50px;

}

```

以上表示固定列宽为 200px 200px 200px,行高为 50px 50px

上述代码可以看到重复写单元格宽高,通过使用`repeat()`函数,可以简写重复的值

- 第一个参数是重复的次数

- 第二个参数是重复的值

所以上述代码可以简写成

```css

.wrapper {

  display: grid;

  grid-template-columns: repeat(3,200px);

  grid-gap: 5px;

  grid-template-rows:repeat(2,50px);

}

```

除了上述的`repeact`关键字,还有:

- auto-fill:示自动填充,让一行(或者一列)中尽可能的容纳更多的单元格

>`grid-template-columns: repeat(auto-fill, 200px)` 表示列宽是 200 px,但列的数量是不固定的,只要浏览器能够容纳得下,就可以放置元素

- fr:片段,为了方便表示比例关系

>`grid-template-columns: 200px 1fr 2fr` 表示第一个列宽设置为 200px,后面剩余的宽度分为两部分,宽度分别为剩余宽度的 1/3 和 2/3

- minmax:产生一个长度范围,表示长度就在这个范围之中都可以应用到网格项目中。第一个参数就是最小值,第二个参数就是最大值

>`minmax(100px, 1fr)`表示列宽不小于`100px`,不大于`1fr`

- auto:由浏览器自己决定长度

>`grid-template-columns: 100px auto 100px` 表示第一第三列为 100px,中间由浏览器决定长度

### grid-row-gap 属性, grid-column-gap 属性, grid-gap 属性

`grid-row-gap` 属性、`grid-column-gap` 属性分别设置行间距和列间距。`grid-gap` 属性是两者的简写形式

`grid-row-gap: 10px` 表示行间距是 10px

`grid-column-gap: 20px` 表示列间距是 20px

`grid-gap: 10px 20px` 等同上述两个属性

### grid-template-areas 属性

用于定义区域,一个区域由一个或者多个单元格组成

```css

.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`的九个区域,分别对应这九个单元格。

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

 ```css

 grid-template-areas: 'a a a'

                      'b b b'

                      'c c c';

 ```

上面代码将9个单元格分成`a`、`b`、`c`三个区域

如果某些区域不需要利用,则使用"点"(`.`)表示

### grid-auto-flow 属性

划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。

顺序就是由`grid-auto-flow`决定,默认为行,代表"先行后列",即先填满第一行,再开始放入第二行

 ![](https://static.vue-js.com/70fb3240-9a94-11eb-ab90-d9ae814b240d.png)

当修改成`column`后,放置变为如下:

![](https://static.vue-js.com/7c26ffa0-9a94-11eb-ab90-d9ae814b240d.png)

### justify-items 属性, align-items 属性, place-items 属性

`justify-items` 属性设置单元格内容的水平位置(左中右),`align-items` 属性设置单元格的垂直位置(上中下)

两者属性的值完成相同

```css

.container {

  justify-items: start | end | center | stretch;

  align-items: start | end | center | stretch;

}

```

属性对应如下:

- start:对齐单元格的起始边缘

- end:对齐单元格的结束边缘

- center:单元格内部居中

- stretch:拉伸,占满单元格的整个宽度(默认值)

`place-items`属性是`align-items`属性和`justify-items`属性的合并简写形式

### justify-content 属性, align-content 属性, place-content 属性

`justify-content`属性是整个内容区域在容器里面的水平位置(左中右),`align-content`属性是整个内容区域的垂直位置(上中下)

```css

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

}

```

两个属性的写法完全相同,都可以取下面这些值:

- start - 对齐容器的起始边框

- end - 对齐容器的结束边框

- center - 容器内部居中

 ![](https://static.vue-js.com/9d1ec990-9a94-11eb-ab90-d9ae814b240d.png)

- space-around - 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍

- space-between - 项目与项目的间隔相等,项目与容器边框之间没有间隔

- space-evenly - 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔

- stretch - 项目大小没有指定时,拉伸占据整个网格容器

 ![](https://static.vue-js.com/a620b210-9a94-11eb-85f6-6fac77c0c9b3.png)

### grid-auto-columns 属性和 grid-auto-rows 属性

有时候,一些项目的指定位置,在现有网格的外部,就会产生显示网格和隐式网格

比如网格只有3列,但是某一个项目指定在第5行。这时,浏览器会自动生成多余的网格,以便放置项目。超出的部分就是隐式网格

而`grid-auto-rows`与`grid-auto-columns`就是专门用于指定隐式网格的宽高

关于项目属性,有如下:

### grid-column-start 属性、grid-column-end 属性、grid-row-start 属性以及grid-row-end 属性

指定网格项目所在的四个边框,分别定位在哪根网格线,从而指定项目的位置

- grid-column-start 属性:左边框所在的垂直网格线

- grid-column-end 属性:右边框所在的垂直网格线

- grid-row-start 属性:上边框所在的水平网格线

- grid-row-end 属性:下边框所在的水平网格线

举个例子:

```html

<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号项目的左边框是第二根垂直网格线,右边框是第四根垂直网格线

 ![](https://static.vue-js.com/b7925530-9a94-11eb-ab90-d9ae814b240d.png)

### grid-area 属性

`grid-area` 属性指定项目放在哪一个区域

```css

.item-1 {

  grid-area: e;

}

```

意思为将1号项目位于`e`区域

与上述讲到的`grid-template-areas`搭配使用

### justify-self 属性、align-self 属性以及 place-self 属性

`justify-self`属性设置单元格内容的水平位置(左中右),跟`justify-items`属性的用法完全一致,但只作用于单个项目。

`align-self`属性设置单元格内容的垂直位置(上中下),跟`align-items`属性的用法完全一致,也是只作用于单个项目

 ```css

 .item {

   justify-self: start | end | center | stretch;

   align-self: start | end | center | stretch;

 }

 ```

这两个属性都可以取下面四个值。

 - start:对齐单元格的起始边缘。

  - end:对齐单元格的结束边缘。

 - center:单元格内部居中。

 - stretch:拉伸,占满单元格的整个宽度(默认值)

## 三、应用场景

文章开头就讲到,`Grid`是一个强大的布局,如一些常见的 CSS 布局,如居中,两列布局,三列布局等等是很容易实现的,在以前的文章中,也有使用`Grid`布局完成对应的功能

关于兼容性问题,结果如下:

 ![](https://static.vue-js.com/c24a2b10-9a94-11eb-85f6-6fac77c0c9b3.png)

总体兼容性还不错,但在 IE 10 以下不支持

目前,`Grid`布局在手机端支持还不算太友好

## 参考文献

- https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Grid_Layout

- https://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html

- https://juejin.cn/post/6854573220306255880#heading-2

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容