## 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;
}
```
- 开始
- 微信小程序
- 获取用户信息
- 记录
- HTML
- HTML5
- 文档根节点
- 你真的了解script标签吗?
- 文档结构
- 已经落后的技术
- form表单
- html实体
- CSS
- css优先级 & 设计模式
- 如何编写高效的 CSS 选择符
- 笔记
- 小计
- flex布局
- 细节体验
- Flex
- Grid
- tailwindcss
- JavaScript
- javascript物语
- js函数定义
- js中的数组对象
- js的json解析
- js中数组的操作
- js事件冒泡
- js中的判断
- js语句声明会提前
- cookie操作
- 关于javascript你要知道的
- 关于innerHTML的试验
- js引擎与GUI引擎是互斥的
- 如何安全的修改对象
- 当渲染引擎遇上强迫症
- 不要使用连相等
- 修改数组-对象
- 算法-函数
- 事件探析
- 事件循环
- js事件循环中的上下文和作用域的经典问题
- Promise
- 最佳实践
- 页面遮罩加载效果
- 网站静态文件之思考
- 图片加载问题
- 路由及转场解决方案
- web app
- 写一个页面路由转场的管理工具
- 谈编程
- 技术/思想的斗争
- 前端技术选型分析
- 我想放点html模板代码
- 开发自适应网页
- 后台前端项目的开发
- 网站PC版和移动版的模板方案
- 前后端分离
- 淘宝前后端分离
- 前后端分离的思考与实践(一)
- 前后端分离的思考与实践(二)
- 前后端分离的思考与实践(三)
- 前后端分离的思考与实践(四)
- 前后端分离的思考与实践(五)
- 前后端分离的思考与实践(六)
- 动画
- 开发小技巧
- Axios
- 屏幕适配
- 理论基础
- 思考
- flexible.js原理
- 实验
- rem的坑,为什么要设置成百分比,为什么又是62.5%
- 为什么以一个标准适配的,其它宽度也能同等适配
- 自适应、响应式、弹性布局、屏幕适配
- 适配:都用百分比?
- 番外篇
- 给你看看0.5px长什么样?
- 用事实证明viewport scale缩放不会改变rem元素的大小
- 为什么PC端页面缩放不会影响rem元素
- 究竟以哪个为设备独立像素
- PC到移动端初试
- 深入理解px
- 响应式之栅格系统
- 深入理解px(二)
- 一篇搞定移动端适配
- flex版栅格布局
- 其他
- 浏览器加载初探
- 警惕你的开发工具
- JS模块化
- webpack
- 打包原理
- 异步加载
- gulp
- 命名规范
- 接口开发
- sea.js学习
- require.js学习
- react学习
- react笔记
- vue学习
- vue3
- 工具、技巧
- 临时笔记
- 怎么维护好开源项目
- 待办
- 对前端MVV*C框架的思考
- jquery问题
- 临时
- 好文
- 节流防抖