通知短信+运营短信,5秒速达,支持群发助手一键发送🚀高效触达和通知客户 广告
## Grid [TOC] ---- ### 简介 ```html <style> .container { display: grid; /* display: inline-grid; */ /* 设为网格布局以后,容器子元素(项目)的 float、display: inline-block、display: table-cell、vertical-align 和 column-* 等设置都将失效。 */ } </style> <div class="container"> <div class="item"></div> <div class="item"></div> ... </div> ``` 网格布局,先将容器按网格划分,再定义项目如何在网格上分布。 Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局。Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局。Grid 布局远比 Flex 布局强大。 本文档主要内容是对 https://css-tricks.com/snippets/css/complete-guide-grid 、http://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html 的精简整理,方便快速查阅。 ---- ### 容器属性 #### grid-template-columns、grid-template-rows ```css .container { grid-template-columns: ... ...; /* e.g. 1fr 1fr minmax(10px, 1fr) 3fr repeat(5, 1fr) 50px auto 100px 1fr */ grid-template-rows: ... ...; /* e.g. min-content 1fr min-content 100px 1fr max-content */ } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/template-columns-rows-01.svg) ```css .container { grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end]; grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line]; } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/template-column-rows-02.svg) 使用空格分隔的值列表定义网格的列和行。这些值代表轨道大小,它们之间的空间代表网格线(`[]` 中命名网格线)。 ---- #### 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'; } ``` 一个区域由单个或多个单元格组成,`grid-template-areas` 属性用于定义区域(area),对区域命名,方便项目引用。 一个区域命名不能既跨行又跨列,否则会被认为是无效值: ```css .container { grid-template-areas: 'a a c' 'a e f' 'g h i'; grid-template-areas: 'a b c' 'd d f' 'd h i'; } ``` ---- #### grid-column-gap、grid-row-gap ```css .container { /* standard */ column-gap: <line-size>; row-gap: <line-size>; /* old */ grid-column-gap: <line-size>; grid-row-gap: <line-size>; } ``` ```css .container { grid-template-columns: 100px 50px 100px; grid-template-rows: 80px auto 80px; column-gap: 10px; row-gap: 15px; } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/dddgrid-gap.svg) 指定网格线的大小,即设置 列/行之间的间隔宽度。 注意,间隔仅在列/行之间创建,而不在外边缘上。 ---- #### justify-items ```css .container { justify-items: start | end | center | stretch; } ``` 定义项目在网格内的行轴方向上的对齐方式(左右对齐)。也可以通过 `justify-self` 属性在单个项目上设置此行为。 ```css .container { justify-items: start; } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/justify-items-start.svg) ---- #### align-items ```css .container { align-items: start | end | center | stretch; } ``` 定义项目在网格内的列轴方向上的对齐方式(上下对齐)。也可以通过 `align-self` 属性在单个项目上设置此行为。 ```css .container { align-items: start; } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/align-items-start.svg) ---- #### justify-content 如果网格区域的总大小小于其网格容器的大小时,此属性可以定义 所有网格 在 网格容器中的行轴方向上的对齐方式(左右对齐)。 ```css .container { justify-content: start | end | center | stretch | space-around | space-between | space-evenly; } ``` ```css .container { justify-content: center; } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/justify-content-center.svg) ---- #### align-content 类似 `justify-content` 属性,此属性可以定义 所有网格 在 网格容器中的列轴方向上的对齐方式(上下对齐)。 ```css .container { align-content: start | end | center | stretch | space-around | space-between | space-evenly; } ``` ```css .container { align-content: start; } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/align-content-start.svg) ---- #### grid-auto-columns、grid-auto-rows ```css .container { grid-auto-columns: <track-size> ...; grid-auto-rows: <track-size> ...; } ``` 指定任何自动生成的栅格轨迹(也称为隐式栅格轨迹)的大小。当容器中的项目比单元格多时,或者当网格项放置在显式网格之外时,将创建隐式轨迹。 为了说明如何创建隐式网格轨迹,请考虑以下内容: ```css .container { grid-template-columns: 60px 60px; grid-template-rows: 90px 90px; } .item-a { grid-column: 1 / 2; grid-row: 2 / 3; } .item-b { grid-column: 5 / 6; grid-row: 2 / 3; } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/grid-auto-columns-rows-02.svg) 我们告诉`.item-b`从列第5行开始,到列第6行结束,但我们从未定义列第5行或第6行。因为我们引用了不存在的线,所以创建了宽度为0的隐式轨迹来填充间隙。(其实自动生成的轨道[不是0](https://jsbin.com/wutofafoyi/edit?html,css,output),并且每个轨道都是同等宽度,包括最后的项目所在轨道。) 我们可以使用 `grid-auto-columns` 和 `grid-auto-rows` 来指定这些隐式轨迹的宽度: ```css .container { grid-auto-columns: 60px; } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/grid-auto-columns-rows-03.svg) (`item-b` 项目所在的轨道宽度也是 `60px`) ---- #### grid-auto-flow ```css .container { grid-auto-flow: row | column | row dense | column dense; } ``` 如果项目没有显式放置在网格上(默认情况),则自动放置算法会自动放置这些项目。此属性控制自动放置算法的工作方式。 ```css .container { display: grid; grid-template-columns: 60px 60px 60px 60px 60px; grid-template-rows: 30px 30px; grid-auto-flow: row; } ``` 观察我们没有放置的三个项目 b、c、d 是如何在可用行中流动的: ![](https://css-tricks.com/wp-content/uploads/2018/11/grid-auto-flow-01.svg) 如果我们将 `grid-auto-flow`设置为 `column`,则 `item-b`,`item-c`,`item-d` 将沿着列向下流动: ```css .container { grid-auto-flow: column; } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/grid-auto-flow-02.svg) ---- ### 项目属性 #### grid-column-start、grid-column-end、grid-row-start、grid-row-end ```css .item { grid-column-start: <number> | <name> | span <number> | span <name> | auto; grid-column-end: <number> | <name> | span <number> | span <name> | auto; grid-row-start: <number> | <name> | span <number> | span <name> | auto; grid-row-end: <number> | <name> | span <number> | span <name> | auto; } ``` 通过引用网格线来确定项目在网格中的位置。 ```css .item-a { grid-column-start: 2; grid-column-end: five; grid-row-start: row1-start; grid-row-end: 3; } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/grid-column-row-start-end-01.svg) 如果没有声明 `grid-column-end` / `grid-row-end`,则默认情况下该项目将跨越1个轨道。 项目可以相互重叠。您可以使用 `z-index` 来控制它们的堆叠顺序。 这四个属性的值还可以使用 `span` 关键字(不要用关键字做网格线名称),表示"跨越",即左右边框(上下边框)之间跨越多少个网格。 ```css .item-1 { grid-column-start: span 2; /* 两者效果一样 */ /* grid-column-end: span 2; */ } ``` 上面代码表示,1号项目的左边框距离右边框跨越2个网格。 如果多个行共享相同的名称,则可以通过它们的行名称和计数来引用它们。 ```css .item { grid-column-start: col-start 2; } ``` ---- #### grid-area 通过引用 `grid-template-areas` 定义的区域,指定项目放在哪一个区域。 该属性也可以用作 `grid-row-start` 、 `grid-column-start` 、 `grid-row-end` 、`grid-column-end` 的简写。 ```css .item { grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>; } ``` ```css .item-d { grid-area: header; } /* or */ .item-d { grid-area: 1 / col4-start / last-line / 6; } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/grid-area.svg) ---- #### justify-self 定义项目在网格内的行轴方向的对齐方式(左右对齐)。用于覆盖 `justify-items` 的配置。 ```css .item { justify-self: start | end | center | stretch; } ``` ```css .item-a { justify-self: start; } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/justify-self-start.svg) ---- #### align-self 定义项目在网格内的列轴方向的对齐方式(上下对齐)。用于覆盖 `align-items` 的配置。 ```css .item { align-self: start | end | center | stretch; } ``` ```css .item-a { align-self: start; } ``` ![](https://css-tricks.com/wp-content/uploads/2018/11/align-self-start.svg) 要对齐网格中的所有项目,也可以通过 `align-items` 属性在网格容器上设置此行为。 ---- ### 属性简写 #### grid-template `grid-template-rows` 、 `grid-template-columns` 和 `grid-template-areas` 的简写。 ```css .container { grid-template: [row1-start] "header header header" 25px [row1-end] [row2-start] "footer footer footer" 25px [row2-end] / auto 50px auto; } /*等价于:*/ .container { grid-template-rows: [row1-start] 25px [row1-end row2-start] 25px [row2-end]; grid-template-columns: auto 50px auto; grid-template-areas: "header header header" "footer footer footer"; } ``` 由于 `grid-template` 不会重置隐式网格属性( `grid-auto-columns` 、 `grid-auto-rows` 和 `grid-auto-flow` ),这可能是您在大多数情况下想要做的,因此建议使用 `grid` 属性而不是 `grid-template` 。 ---- #### grid-gap `row-gap` 和 `column-gap` 的缩写。 ```css .container { /* standard */ gap: <grid-row-gap> <grid-column-gap>; /* old */ grid-gap: <grid-row-gap> <grid-column-gap>; } ``` 如果未指定 `row-gap` ,则将其设置为与 `column-gap` 相同的值。 ---- #### place-items `align-items` 和 `justify-items` 的简写。 ```css .center { display: grid; place-items: start center; } ``` 第一个值设置 `align-items` ,第二个值设置 `justify-items` 。如果省略第二个值,则将第一个值分配给两个属性。 ---- #### place-self `align-self` 和 `justify-self` 属性的简写。 ```css .item-a { place-self: center stretch; } ``` 第一个值设置 `align-self` ,第二个值设置 `justify-self` 。如果省略第二个值,则将第一个值分配给两个属性。 ---- #### place-content `align-content` 和 `justify-content` 的简写。 ```css .container { place-content: start center; } ``` 第一个值设置 `align-content` ,第二个值设置 `justify-content` 。如果省略第二个值,则将第一个值分配给两个属性。 ---- #### grid `grid-template-rows` 、 `grid-template-columns` 、 `grid-template-areas` 、 `grid-auto-rows` 、 `grid-auto-columns` 和 `grid-auto-flow` 等属性的简写。(注意:在单个网格声明中只能指定显式或隐式网格属性)。 以下两个代码块是等效的: ```css .container { grid: 100px 300px / auto-flow 200px; } .container { grid-template-rows: 100px 300px; grid-auto-flow: column; grid-auto-columns: 200px; } ``` ---- #### grid-column `grid-column-start` 、 `grid-column-end` 的缩写。 ```css .item { grid-column: <start-line> / <end-line> | <start-line> / span <value>; } ``` 如果没有声明结束线值,则默认情况下项目将跨越1个轨道。 ---- #### grid-row `grid-row-start` 、 `grid-row-end` 的缩写。 ```css .item { grid-row: <start-line> / <end-line> | <start-line> / span <value>; } ``` ---- #### grid-area `grid-row-start`、`grid-column-start`、`grid-row-end`、`grid-column-end`的简写。 ```css .item-d { grid-area: 1 / col4-start / last-line / 6; } ``` ---- ### 特殊单位和函数说明 #### repeat() 有时候,重复写同样的值非常麻烦,尤其网格很多时。这时,可以使用`repeat()`函数,简化重复的值。上面的代码用`repeat()`改写如下: ```css .container { display: grid; grid-template-columns: repeat(3, 33.33%); grid-template-rows: repeat(3, 33.33%); } ``` `repeat()`接受两个参数,第一个参数是重复的次数(上例是3),第二个参数是所要重复的值。 `repeat()`重复某种模式也是可以的: ```css .container { grid-template-columns: repeat(2, 100px 20px 80px); } ``` 传统的十二网格布局,写起来也很容易: ```css .container { grid-template-columns: repeat(12, 1fr); } ``` ---- #### minmax() `minmax()`函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。 ```css .container { grid-template-columns: 1fr 1fr minmax(100px, 1fr); } ``` 上面代码中,`minmax(100px, 1fr)`表示列宽不小于`100px`,不大于`1fr`。 ---- #### fit-content() 函数使用可用的空间,但不会小于 `min-content`,也不会大于 `max-content`。 ----- #### fr 关键字 为了方便表示比例关系,网格布局提供了`fr`关键字(fraction 的缩写,意为"片段")。如果两列的宽度分别为`1fr`和`2fr`,就表示后者是前者的两倍。 ```css .container { display: grid; grid-template-columns: 1fr 1fr; } ``` [上面代码](https://jsbin.com/hadexek/edit?html,css,output)表示两个相同宽度的列。 ![](https://www.wangbase.com/blogimg/asset/201903/1_bg2019032509.png) `fr`可以与绝对长度的单位结合使用,这时会非常方便。 ```css .container { display: grid; grid-template-columns: 150px 1fr 2fr; } ``` [上面代码](https://jsbin.com/remowec/edit?html,css,output)表示,第一列的宽度为150像素,第二列的宽度是第三列的一半。 ![](https://www.wangbase.com/blogimg/asset/201903/bg2019032510.png) ---- #### auto、min-content、max-content 关键字 **auto:** `auto`关键字表示由浏览器自己决定长度。 ```css .container { grid-template-columns: 100px auto 100px; } ``` 上面代码中,第二列的宽度,基本上等于该列单元格的最大宽度,除非单元格内容设置了`min-width`,且这个值大于最大宽度。 **min-content:** 内容的最小大小。想象一行像“E pluribus unum”这样的文本,最小内容可能是单词“pluribus”的宽度。 **max-content:** 内容的最大大小。想象一下上面的句子,`max-content` 是整个句子的长度。 ---- #### auto-fill 关键字 有时,单元格的大小是固定的,但是容器的大小不确定。如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用`auto-fill`关键字表示自动填充。 ```css .container { display: grid; grid-template-columns: repeat(auto-fill, 100px); } ``` [上面代码](https://jsbin.com/himoku/edit?css,output)表示每列宽度`100px`,然后自动填充,直到容器不能放置更多的列。 ![](https://www.wangbase.com/blogimg/asset/201903/bg2019032508.png) 除了`auto-fill`,还有一个关键字`auto-fit`,两者的行为基本是相同的。只有当容器足够宽,可以在一行容纳所有单元格,并且单元格宽度不固定的时候,才会有[行为差异](https://css-tricks.com/auto-sizing-columns-css-grid-auto-fill-vs-auto-fit/):`auto-fill`会用空格子填满剩余宽度,`auto-fit`则会尽量扩大单元格的宽度。 ---- #### auto-fit 关键字 将所有列都放入空间中。更喜欢扩展列来填充空间,而不是空列。 这是 CSS Grid 中最著名的片段,也是有史以来最伟大的 CSS 技巧之一: ```css .container { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); } ``` `auto-fill` `auto-fit` 区别见: https://css-tricks.com/auto-sizing-columns-css-grid-auto-fill-vs-auto-fit/ ---- #### Subgrid 子栅格 子网格是网格的一个非常有用的功能,它允许网格项拥有自己的网格,并从父网格继承网格线。(目前只有 Firefox 支持这一功能) ```css .parent-grid { display: grid; grid-template-columns: repeat(9, 1fr); } .grid-item { grid-column: 2 / 7; display: grid; grid-template-columns: subgrid; } .child-of-grid-item { /* gets to participate on parent grid! */ grid-column: 3 / 6; } ```