CSS Grid Layout,旨在彻底改变咱们处理网格的方式,它是二维表格系统。CSS 常常被用来布局,即便它表现得不是很出色。起初,咱们使用tabels、floats、position 和 inline-block,但全部这些方法基本上都是黑科技,并会遗漏许多重要功能(例如垂直居中)。Flexbox 在这方便帮了忙,但它的目标是简单的一维布局,而不是复杂的二维布局。(事实上,Flexbox 和 Grid 能很好地协做。)Grid 是第一个设计出来用于布局的 CSS 模块。css
开始你要用 display: grid
定义一个表格容器,用 grid-template-columes
和 grid-template-rows
设置列和行的尺寸,而后将子元素放在表格的列和行中。跟 Flexbox
类似,网格项的顺序可有可无。您的 CSS 能够将它们任意排序,使用媒体查询来重排布局也很是容易。想象一下,定义整个页面的布局,而后只需几行 CSS 就能彻底从新排列它来适应不一样的屏幕宽度,Grid 是有史以来最强大的 CSS 模块之一。html
截至2017年3月,大多数浏览器都提供原生的,没有前缀的 CSS Grid 支持:Chrome(包括Android),Firefox,Safari(包括iOS)和Opera。另外一方面,Internet Explorer 10 和11支持它,但它是一种过期语法。如今是用 Grid 构建的时候了!git
Chrome | Opera | Firefox | IE | Edge | Safari |
---|---|---|---|---|---|
57 | 44 | 52 | 11* | 16 | 10.1 |
iOS Safari | Opera Mobile | Opera Mini | Android | Android Chrome | Android Firefox |
---|---|---|---|---|---|
10.3 | 46 | No | 67 | 74 | 67 |
在深刻研究 Grid 以前,理解术语很是重要。因为这里涉及的术语在概念上都类似,若是你不首先记住网格规范定义的含义,很容易将它们彼此混淆。但别担忧,它们并很少。github
应用 display: grid
的元素,它是表格项的直接父元素。在下面例子中, container 就是网格容器。算法
<div class="container">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>
复制代码
它是网格容器的直接子元素,下面例子中 item 就是网格项,但 sub-item 不是。浏览器
<div class="container">
<div class="item"></div>
<div class="item">
<p class="sub-item"></p>
</div>
<div class="item"></div>
</div>
复制代码
网格结构的分割线。有垂直(网格列线)、水平(网格行线)、驻留在行和列两侧的线。下面黄色的就是网格列线。ide
两个相邻网格线之间的空间。你能把它们想象成是网格列或行。下面的网格轨道就是第二条和第三条行线之间的空间。svg
两个相邻行和两个相邻列网格线之间的空间。它是网格的单个“单元”。这是行网格线1和2以及列网格线2和3之间的网格单元。函数
四个网格线包围的总空间。网格区域能够包括任意数量的网格单元。这是行网格线1和3以及列网格线1和3之间的网格区域。布局
将元素定义为网格容器,并为其内容创建新的网格格式上下文。
值:
grid - 产生块级网格
inline-grid - 产生内联级网格
.container {
display: grid | inline-grid;
}
复制代码
使用以空格分隔的值列表定义网格的列和行。值表示轨道大小,它们之间的空间表示网格线。
值:
<track-size>
- 能够是一段长度、百分比、或者表格空间中的一部分(使用 fr
单位)
<line-name>
- 您选择的任意名称
.container {
grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}
复制代码
举例,当您在轨道值之间留出空白区域时,网格线会自动分配正数和负数:
.container {
grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 25% 100px auto;
}
复制代码
但您能够选择明确命名行。请注意行名称的括号语法:
.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];
}
复制代码
请注意,一行能够有多个名称。例如,这里第二行将有两个名称:row1-end
和 row2-start
:
.container {
grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}
复制代码
若是您的定义包含重复部分,你可使用 repeat()
方法来简化:
.container {
grid-template-columns: repeat(3, 20px [col-start]);
}
复制代码
上面代码等价于:
.container {
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start];
}
复制代码
若是多行共享相同的名称,则能够经过其行名称和计数来引用它们。
.item {
grid-column-start: col-start 2;
}
复制代码
fr
单元容许您将轨道的大小设置为网格容器的可用空间的一部分。例如,这会将每一个项目设置为网格容器宽度的三分之一:
.container {
grid-template-columns: 1fr 1fr 1fr;
}
复制代码
在任何非灵活项目以后计算可用空间。在此示例中,fr
单元可用的总可用空间量不包括50px:
.container {
grid-template-columns: 1fr 50px 1fr 1fr;
}
复制代码
经过引用使用
grid-area
属性指定的网格区域的名称来定义网格模板。重复网格区域的名称会致使内容跨越这些单元格。句点表示空单元格。语法自己提供了网格结构的可视化。
值:
<grid-area-name>
- 用 grid-area
制定的网格区域名称
.
- 句点表示空白网格区域
none
- 没有定义网格区域
.container {
grid-template-areas:
"<grid-area-name> | . | none | ..."
"...";
}
复制代码
举例:
.item-a {
grid-area: header;
}
.item-b {
grid-area: main;
}
.item-c {
grid-area: sidebar;
}
.item-d {
grid-area: footer;
}
.container {
display: grid;
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";
}
复制代码
这将建立一个四列宽三行高的网格。整个顶行将由标题区域组成。中间行将包括两个主要区域,一个空单元格和一个侧边栏区域。最后一行是全部页脚。
声明中的每一行都须要具备相同数量的单元格。
您可使用任意数量的相邻句点来声明单个空单元格。只要它们之间没有空格,它们就表明一个单元格。
请注意,您没有使用此语法命名行,而只是命名了区域。使用此语法时,区域两端的线条实际上会自动命名。若是网格区域的名称为 foo
,则区域的起始行和起始列行的名称将为 foo-start
,其最后一行和最后一行的名称将为 foo-end
。这意味着某些行可能有多个名称,例如上例中的最左边的行,它将有三个名称:header-start
,main-start
和 footer-start
。
在单个声明中设置
grid-template-rows
,grid-template-columns
和grid-template-areas
的简写。
值:
none
- 设置3个属性为它们的初始值
<grid-template-rows> / <grid-template-columns>
- 设置 grid-template-columns
和 grid-template-rows
为特定值,设置 grid-template-areas
为 none
.container {
grid-template: none | <grid-template-rows> / <grid-template-columns>;
}
复制代码
它也能接受一个复杂且包含三者的语法,下面是个例子:
.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
),这多是你想要在大多数状况下作的,因此建议使用网格属性而不是网格模板。
指定网格线的大小。您能够将其视为设置列/行之间的装订线宽度。
值:
<line-size>
- 一个长度值
.container {
grid-column-gap: <line-size>;
grid-row-gap: <line-size>;
}
复制代码
举例:
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-column-gap: 10px;
grid-row-gap: 15px;
}
复制代码
间距只能在行和列之间产生,外边没法设置间距。
注意:grid-column-gap
和 grid-row-gap
的 前缀 grid-
被移除,并被从新命名成 column-gap
和 row-gap
。 无前缀属性已经获得 Chrome 68+、Safari 11.二、Opera 54+ 的支持。
grid-row-gap
和grid-column-gap
的简写
值:
<grid-row-gap> <grid-column-gap>
- 长度值
.container {
grid-gap: <grid-row-gap> <grid-column-gap>;
}
复制代码
举个例子:
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-gap: 15px 10px;
}
复制代码
若是没有 grid-row-gap
被定义,它将被设置成跟 grid-column-gap
同样的值。
注意: grid-gap
的前缀也被移除了,被从新命名成 gap
。也获得了 Chrome 68+ 、 Safari 11.2+ 和 Opera 54+ 的支持。
沿着内联(行)轴对齐网格项(而不是沿着块(列)轴对齐的对齐项)。此值适用于容器内的全部网格项。
值:
strat
- 与单元格的起始边缘对奇
end
- 与单元格的结束边缘对齐
center
- 与单元的中心对齐
stretch
- 拉伸使其充满整个单元格(默认值)
.container {
justify-items: start | end | center | stretch;
}
复制代码
举例:
.container {
justify-items: start;
}
复制代码
.container {
justify-items: end;
}
复制代码
.container {
justify-items: center;
}
复制代码
.container {
justify-items: stretch;
}
复制代码
这些行为也能经过网格项的 justify-self
来从新定义。
沿着列网格线对齐网格项(而不是沿着行网格线对齐的对齐项)。此值适用于容器内的全部网格项。
值:
start
- 将其与单元格上边缘对齐
end
- 将其与单元格下边缘对齐
center
- 将其与单元格中间对齐
stretch
- 竖向延伸到整个单元格
.container {
align-items: start | end | center | stretch;
}
复制代码
举例:
.container {
align-items: start;
}
复制代码
.container {
align-items: end;
}
复制代码
.container {
align-items: center;
}
复制代码
.container {
align-items: stretch;
}
复制代码
这个表现也可以经过 align-self
去单独设置网格单元。
place-items
一个声明可以同时设置align-items
和justify-items
两个属性
值:
<align-items> / <justify-items>
- 第一个值设置 align-items
,第二个值设置 justify-items
。若是没有第二个值,则两个属性的值同样。除 Edge
以外的全部主流浏览器都支持 place-items
属性。
有时您的内容区域可能会小于整个网格区域。若是您的全部网格项都使用非灵活单位(如
px
)进行大小调整,则可能会发生这种状况。在这种状况下,您能够在网格容器中设置网格的对齐方式。此属性沿着内联(行)轴对齐网格(而不是沿着块(列)轴对齐网格的对齐内容)。
值: start
- 将网格与网格容器的起始边缘齐平
end
- 将网格与网格容器的结束边缘齐平
center
- 将网格与网格容器的中间齐平
stretch
- 调整网格项的大小以容许网格填充网格容器的整个宽度
space-around
- 在每一个网格项之间放置一个均匀的空间,在远端放置半个大小的空格
space-between
- 在每一个网格项之间放置一个偶数空间,在远端没有空格
space-evenly
- 在每一个网格项之间放置一个均匀的空间,包括远端
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
复制代码
举例:
.container {
justify-content: start;
}
复制代码
.container {
justify-content: end;
}
复制代码
.container {
justify-content: center;
}
复制代码
.container {
justify-content: stretch;
}
复制代码
.container {
justify-content: space-around;
}
复制代码
.container {
justify-content: space-between;
}
复制代码
.container {
justify-content: space-evenly;
}
复制代码
有时网格总尺寸会比网格容器小。在网格项用非弹性单位(例如
px
)设置尺寸时会发生这种现象。这种状况下你可以设置网格的对准方式。这个属性是设置列轴的对齐方式,上面所讲的justify-content
则是设置行轴方向的!
值:
start
- 将网格对齐在网格容器的上起始边缘线
end
- 将网格对齐在网格容器的下边缘线
center
- 将网格对齐在网格容器的中心
stretch
- 讲网格拉伸充满整个网格容器
space-around
- 在每一个行网格项之间放置一个均匀的空间,在两端放置半个大小的空格
space-between
- 在每一个行网格项之间放置一个均匀的空间,两端没有空格
space-evenly
- 在每一个行网格项之间和两端放置一个均匀的空间
.container {
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
复制代码
举例:
.container {
align-content: start;
}
复制代码
.container {
align-content: end;
}
复制代码
.container {
align-content: center;
}
复制代码
.container {
align-content: stretch;
}
复制代码
.container {
align-content: space-around;
}
复制代码
.container {
align-content: space-between;
}
复制代码
.container {
align-content: space-evenly;
}
复制代码
place-content
是同时设置justify-content
和align-content
的简写形式
值:
<align-content>/<justify-content>
- 第一个值设置 align-conent
,第二个值设置 justify-content
。若是第二个值被忽略,那么第一个值就对两个属性生效。
指定任何自动生成的网格轨道的大小(也称为隐式网格轨道)。当网格项目多于网格中的单元格或网格项目放置在显式网格以外时,将建立隐式轨道。
值: <track-size>
- 能够是一个长度、百分比、或者是 fr
单位。
.container {
grid-auto-columns: <track-size> ...;
grid-auto-rows: <track-size> ...;
}
复制代码
为了说明如何建立隐式网格轨道,请考虑如下事项:
.container {
grid-template-columns: 60px 60px;
grid-template-rows: 90px 90px
}
复制代码
上述代码建立了 2*2 的网格。
.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}
复制代码
咱们设置 .item-b 的宽度在第五列和第六列之间,可是咱们没有定义这两列。由于咱们引用了不存在的行,因此建立宽度为0的隐式轨道以填充间隙。咱们可使用 grid-auto-columns
和 grid-auto-rows
来指定这些隐式轨道的宽度:
.container {
grid-auto-columns: 60px;
}
复制代码
若是您没有明确放置在网格上的网格项,则自动放置算法会自动放置项目。此属性控制自动放置算法的工做方式。
值:
row
- 告诉自动放置算法依次填充每一行,根据须要添加新行(默认值)
column
- 告诉自动放置算法依次填写每一个列,根据须要添加新列
dense
- 告诉自动放置算法,若是稍后出现较小的项目,则尝试填充网格中较早的空闲位置
.container {
grid-auto-flow: row | column | row dense | column dense
}
复制代码
注意,dense 只会更改项目的可视顺序,并可能致使它们出现乱序,这不利于可访问性。
例子:
<section class="container">
<div class="item-a">item-a</div>
<div class="item-b">item-b</div>
<div class="item-c">item-c</div>
<div class="item-d">item-d</div>
<div class="item-e">item-e</div>
</section>
复制代码
经过下面的 css 将网格设置成5列2行,设置 grid-auto-flow
值为 row
(该属性的默认值):
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: row;
}
复制代码
而后咱们在网格项中放置项目:
.item-a {
grid-column: 1;
grid-row: 1 / 3;
}
.item-e {
grid-column: 5;
grid-row: 1 / 3;
}
复制代码
咱们设置了 grid-auto-flow: row;
咱们的网格以下图所示。请注意咱们没有放置的3项(item-b,item-c,item-d):
若是咱们将 grid-auto-flow 设置成 column ,效果以下:
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: column;
}
复制代码
设置如下属性的简写形式(包括
grid-template-rows
、grid-template-columns
、grid-auto-rows
、grid-auto-columns
和grid-auto-flow
)(注意:您只能在单个网格声明中指定显式或隐式网格属性)
值:
none
- 将全部子属性设置为初始值
<grid-template>
- 跟 grid-template
同样
<grid-template-rows>/[auto-flow && dense?]<grid-auto-columns>?
- 将 grid-template-rows
设置为指定的值。若是 auto-flow
关键字位于斜杠的右侧,则会将 grid-auto-flow
设置为 column
。若是另外指定了密集关键字,则自动放置算法使用“密集”打包算法。若是省略 grid-auto-columns
,则将其设置为 auto
。
[ auto-flow && dense? ]<grid-auto-rows>?/<grid-template-columns>
- 将 grid-template-columns
设置为指定的值。若是 auto-flow
关键字位于斜杠的左侧,则会将 grid-auto-flow
设置为 row
。若是另外指定了 dense
关键字,则自动放置算法使用 “dense
” 打包算法。若是省略 grid-auto-rows
,则将其设置为 auto
。
例子:
下面两个代码块是等价的:
.container {
grid: 100px 300px / 3fr 1fr;
}
复制代码
.container {
grid-template-rows: 100px 300px;
grid-template-columns: 3fr 1fr;
}
复制代码
下面两个代码块也是等价的:
.container {
grid: auto-flow / 200px 1fr;
}
复制代码
.container {
grid-auto-flow: row;
grid-template-columns: 200px 1fr;
}
复制代码
下面两个代码块也是等价的:
.container {
grid: auto-flow dense 100px / 1fr 2fr;
}
复制代码
.container {
grid-auto-flow: row dense;
grid-auto-rows: 100px;
grid-template-columns: 1fr 2fr;
}
复制代码
下面两个代码块也是等价的:
.container {
grid: 100px 300px / auto-flow 200px;
}
复制代码
.container {
grid-template-rows: 100px 300px;
grid-auto-flow: column;
grid-auto-columns: 200px;
}
复制代码
它还接受一个更复杂但很是方便的语法来一次设置全部内容。您能够指定 grid-template-areas
,grid-template-rows
和 grid-template-columns
,并将全部其余子属性设置为其初始值。您正在作的是指定行名称和轨道大小与其各自的网格区域内联。用一个例子来帮助理解:
.container {
grid: [row1-start] "header header header" 1fr [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
复制代码
上面代码等价于:
.container {
grid-template-areas:
"header header header"
"footer footer footer";
grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
}
复制代码
注意:
float
、display: inline-block
、display: table-cell
、vertical-align
和column-*
属性对网格没有影响。
经过网格线来决定网格项在网格容器中的位置。顾名思义,
grid-column-start
/grid-row-start
决定了网格项的起始边缘,grid-column-end
/grid-row-end
决定了网格项的结束边缘。
值:
line
- 能够是指定网格线的数字或者其余命名
span<number>
- 该项目将跨越提供的网格轨道数量
span<name>
- 该项目将跨越,直到它使用提供的名称命中下一行
auto
- 自动放置,自动和默认跨度都默认是1
.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;
}
复制代码
举例:
.item-a {
grid-column-start: 2;
grid-column-end: five;
grid-row-start: row1-start
grid-row-end: 3;
}
复制代码
.item-b {
grid-column-start: 1;
grid-column-end: span col4-start;
grid-row-start: 2
grid-row-end: span 2
}
复制代码
若是没有声明 grid-column-end
/ grid-row-end
,网格项默认跨越一个轨道。
网格项会堆叠,可使用 z-index
控制堆叠顺序。
grid-column-start
+grid-column-end
和grid-row-start
+grid-row-end
的简写。
值:
<start-line>/<end-line>
- 每一个属性接收跟单个一样的值,包括span
.item {
grid-column: <start-line> / <end-line> | <start-line> / span <value>;
grid-row: <start-line> / <end-line> | <start-line> / span <value>;
}
复制代码
举例:
.item-c {
grid-column: 3 / span 2;
grid-row: third-line / 4;
}
复制代码
没有声明结束线时,网格项默认跨越一个轨道。
为网格项指定名称,以即可以使用
grid-template-areas
属性建立的模板引用该项目。或者,此属性可用做网格行开始 + 网格列开始 + 网格行结束 + 网格列结束的更短的简写。
值:
<name>
- 一个名称
<row-start>/<column-start>/<row-end>/<column-end>
- 能够是数字或命名行
.item {
grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
}
复制代码
举例:
下面给网格项设置一个名称:
.item-d {
grid-area: header;
}
复制代码
做为 grid-row-start
+ grid-column-start
+ grid-row-end
+ grid-column-end
的简写:
.item-d {
grid-area: 1 / col4-start / last-line / 6;
}
复制代码
沿着行轴对齐单元格内的网格项,此值适用于单个单元格内的网格项。
值:
start
- 将网格项对齐以与单元格的起始边缘齐平
end
- 将网格项对齐以与单元格的结束边缘齐平
center
- 对齐单元格中心的网格项
stretch
- 填充整个单元格的宽度
.item {
justify-self: start | end | center | stretch;
}
复制代码
举例:
.item-a {
justify-self: start;
}
复制代码
.item-a {
justify-self: end;
}
复制代码
.item-a {
justify-self: center;
}
复制代码
.item-a {
justify-self: stretch;
}
复制代码
若是要设置全部网格项的行轴对齐方式,能够经过网格容器属性 justify-items
。
沿着列轴对齐单元格内的网格项,此值适用于单个网格项内的内容。
值:
start
- 将网格项与单元格的上边缘齐平
end
- 将网格项与单元格的下边缘齐平
center
- 将网格项与单元格的中心对齐
stretch
- 填充整个单元格的高度
.item {
align-self: start | end | center | stretch;
}
复制代码
举例:
.item-a {
align-self: start;
}
复制代码
.item-a {
align-self: end;
}
复制代码
.item-a {
align-self: center;
}
复制代码
.item-a {
align-self: stretch;
}
复制代码
若是要设置网格容器全部项的列轴对齐方式,能够经过属性 align-items
去设置。
同时设置
align-self
和justify-self
两个属性的简写形式。
值:
auto
- 布局模式的“默认”对齐方式
<align-self>/<justify-self>
- 第一个值设置 align-self
,第二个值设置 justify-align
。若是缺乏第二个值,则对两个属性都生效。
举例:
.item-a {
place-self: center;
}
复制代码
.item-a {
place-self: center stretch;
}
复制代码
全部主流浏览器(除了 Edge
)都支持 place-self
简写属性。
px
、rem
、%
等,你还可使用 min-content
、max-content
、auto
关键字,但最有用的是 fr
单位。grid-template-columns: 200px 1fr 2fr min-content;
fr
)的边界。好比设置列为 1fr
,但缩小到最小 200px
:grid-template-columns: 1fr minmax(200px, 1fr);
repeat()
函数,节省一些字符。好比 10 列同样的宽度:grid-template-columns: repaet(10, 1fr);
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
以为对你有帮助的话,欢迎 star 个人博客!