Skip to main content

grid布局学习笔记

Learn From:

Grid Properties for the Parent (Grid Container)

display

values
  • grid – 生成一个块 grid 布局
  • inline-grid – 生成一个内联 grid 布局
.container {
/* */
display: grid;
/* */
/* display: inline-grid; */
}

grid-template-columns 和 grid-template-rows

使用空格分隔的值列表定义网格的列和行。这些值表示轨道大小,它们之间的间距表示网格线。

Values

<track-size> – 可取 数据值、百分值以及 frfree space)单位等
<line-name> – 可以给 “轨道” 取名字, 以供选择

.container {
grid-template-columns: 40px 50px auto 50px 40px;
/* e.g.
1fr 1fr
minmax(10px, 1fr) 3fr
repeat(5, 1fr)
50px auto 100px 1fr
*/
grid-template-rows: 25% 100px auto;
/* e.g.
min-content 1fr min-content
100px 1fr max-content
*/
}

网格线会自动从这些分配中分配正数(-1 是最后一行)。

grid1

另外,还可以选择显式命名这些行/列,但名字需要加上中括号 [] :

.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]
}

grid2

每个行/列可以有多个名字,名字之间加上空格即可:

.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; /* 名为 col-start 的第二个*/
}

fr 单位允许您将轨道的大小设置为网格容器可用空间的一小部分。例如,下面代码会将每个项目设置为网格容器宽度的三分之一

.container {
grid-template-columns: 1fr 1fr 1fr;
}

可用空间是在任何非 具体数字或百分数项目 之后计算的。下面代码中 fr 单元可用的可用空间总量并不包括 50px

.container {
grid-template-columns: 1fr 50px 1fr;
}

grid-template-areas

定义网格模板,网格元素可以通过使用 grid-area 属性指定的网格区域名称来设置位置。
重复网格区域的名称会导致内容跨越这些单元格。
语法本身提供了网格结构的可视化。

Values:
  • <grid-area-name> – grid-area指定的grid区域名字
  • . – 代表空区域
  • none – 未定义 grid区域

例子:

.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";
}
.item-a {
grid-area: header;
}
.item-b {
grid-area: main;
}
.item-c {
grid-area: sidebar;
}
.item-d {
grid-area: footer;
}

创建一个三行四列的网格。
第一行行将由 header 区域组成。中间行将由两个 main 区域、一个空单元格和一个 sidebar 区域组成。最后一行是所有 footer

grid-area

声明中的每一行都需要具有相同数量的单元格。

可以使用任意数量的 . 来声明单个空单元格。只要之间没有空格,它们就表示单个单元格。

注意

这种方法只能给每个 网格区域 命名,而不能给 网格线 取名。

当您使用此语法时,区域两端的行实际上会自动命名。
如果网格区域的名称为 foo,则该区域的起始行网格线和起始列网格线的名称将为 foo-start,其最后一行网格线和最后一列网格线的名称将为 foo-end
这意味着某些行可能有多个名称,例如上面示例中最左边的网格线,它将有三个名称:header-start, main-start, and footer-start

grid-template

grid-template-rows, grid-template-columns, 和 grid-template-areas 的简写。

例子:

.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 属性

column-gap row-gap grid-column-gap grid-row-gap

指定网格线的大小。您可以将其视为设置列/行之间的间隔的宽度。

Values:

<line-size> – a length value

.container {
/* standard */
column-gap: 10px;
row-gap: 10px;

/* old */
grid-column-gap: 10px;
grid-row-gap: 10px;
}

例子:

.container {
grid-template-columns: repeat(3, 120px);
grid-template-rows: repeat(3, 120px);
column-gap: 10px;
row-gap: 15px;
}

grid-gap

*-gap 规定的是网格区域间行/列的间隔,并不影响与外部的元素间隔。

注意

grid-* 前缀将被删除,grid-column-gapgrid-row-gap 重命名为 column-gaprow-gap。 Chrome 68+、Safari 11.2 Release 50+ 和 Opera 54+ 已经支持无前缀属性。

gap grid-gap

row-gapcolumn-gap 的简写

.container {
/* standard */
/* gap: <grid-row-gap> <grid-column-gap>; */

/* old */
/* grid-gap: <grid-row-gap> <grid-column-gap>; */
}

如果设定了一个值,那么 row-gap column-gap 是一个值。

justify-items

沿着内联(行)轴对齐网格单元(与沿着块(列)轴对齐的align-items相反)。 适用于网格容器内的所有网格单元

可选值
  • start – 网格单元位于单元格的开始
  • end – 网格单元位于单元格的末端
  • center – 网格单元位于单元格中心
  • stretch – 填充单元格的整个宽度(默认)在网格单元没有设置宽高的情况下!

例子:

justify-items_start.png justify-items_end.png justify-items_center.png justify-items_stretch.png

补充

可以在单个网格单元中通过 justify-self 属性来设置对齐方式。

align-items

Aligns grid items along the block (column) axis (as opposed to justify-items which aligns along the inline (row) axis). This value applies to all grid items inside the container.

Values:
  • stretch – 填充单元格的整个高度(默认值),(在网格单元没有设置宽高的情况下!
  • start – 网格单元位于纵轴的开始位置
  • end – 网格单元位于纵轴的结束位置
  • center – 网格单元位于纵轴的中心位置
  • baseline – 沿文本基线对齐项目。基线有修饰符 —— 第一个基线和最后一个基线,在多行文本的情况下,它们将使用第一行或最后一行的基线。

align-items_start.png align-items_end.png align-items_center.png align-items_stretch.png

补充

可以在单个网格单元中通过 align-self 属性来设置对齐方式。

还有修饰符关键字 safeunsafe。用法就像 align-items: safe end
safe 关键字的意思是“尝试像这样对齐,但不会使其移动到无法访问的溢出区域”,
unsafe 将允许将内容移动到无法访问的区域(可能会导致数据丢失)。

place-items

place-itemsalign-itemsjustify-items 的简写

Values:

<align-items> / <justify-items> – 注意第一个值是 align-items
如果省略第二个值,则将第一个值分配给两个属性。

这对于快速定位元素到中心非常有用:

.center {
display: grid;
place-items: center;
}
Result
Loading...
Live Editor

justify-content

有时网格的总大小可能小于其网格容器的大小。如果您的所有网格项目都使用 px 等非灵活单位调整大小,则可能会发生这种情况。
在这种情况下,您可以在网格容器内设置网格的对齐方式。

This property aligns the grid along the inline (row) axis (as opposed to align-content which aligns the grid along the block (column) axis).

Values:
  • start – 网格位于网格容器的开始位置
  • end – 网格位于网格容器的结束位置
  • center – 网格位于网格容器的中心位置
  • stretch – 改变网格项目,允许网格填充整个网格容器(水平方向,即填充所有宽度)(grid-template-rows 的值有为 auto 是才有用!)
  • space-around – 在每个网格项目之间放置均匀的空间,在远端有一半大小的空间
  • space-between – 在每个网格项目之间放置均匀的空间,远端没有空间
  • space-evenly – 在每个网格项目之间放置均匀的空间,包括远端
Result
Loading...
Live Editor

align-content

此属性设置沿块(列)轴对齐网格。
取值与 justify-content 相同!

注意:- stretch属性 只有当grid-template-columns 的值有为 auto 或者不设定该属性时才有用!

Result
Loading...
Live Editor

place-content

place-contentalign-contentjustify-content 的简写

Values:

<align-content> / <justify-content> – 第一个值设定 align-content!第二个值设定 justify-content
如果省略第二个值,则将第一个值分配给两个属性。

grid-auto-columns grid-auto-rows

指定任何自动生成的网格轨迹(又名隐式网格轨迹 implicit grid tracks )的大小。 当网格项多于网格中的单元格或网格项放置在显式网格之外时,会创建隐式轨道。

拓展:The Difference Between Explicit and Implicit Grids)

Values:

<track-size> – can be a length, a percentage, or a fraction of the free space in the grid (using the fr unit)

例子:

Result
Loading...
Live Editor

以上,我们将第二个网格项设置为从第 5 列开始,到第 6 列结束,但我们从未定义第 5 或 6 列。
因为我们引用了不存在的行,所以会创建宽度为 0 的隐式轨道来填充在缝隙中。

grid-auto1.png

我们可以使用 grid-auto-columnsgrid-auto-rows 来指定这些隐式轨道的宽度:

.container {
grid-auto-columns: 60px;
}

grid-auto2.png

grid-auto-rows同理!

grid-auto-flow

如果您有未明确放置在网格上的网格项目,则自动放置算法会启动以自动放置这些项目。
此属性控制自动放置算法的工作方式。

Values
  • row – 告诉自动放置算法依次填充行,并根据需要添加新行(默认值)
  • column – 优先列
  • dense – 尝试在网格中更早地填充
.container {
/* grid-auto-flow: row | column | row dense | column dense; */
}

请注意,dense 只会更改项目的视觉顺序,并可能导致它们出现乱序,这不利于可访问性。

Result
Loading...
Live Editor

grid

grid-template-rows, grid-template-columns, grid-template-areas, grid-auto-rows, grid-auto-columns, 和 grid-auto-flow的简写

Values:
  • none – 全设为默认值
  • <grid-template>
  • <grid-template-rows> / [ auto-flow && dense? ] <grid-auto-columns> ?
    • sets grid-template-rows to the specified value.
    • If the auto-flow keyword is to the right of the slash, it sets grid-auto-flow to column.
    • If the dense keyword is specified additionally, the auto-placement algorithm uses a “dense” packing algorithm.
    • If grid-auto-columns is omitted, it is set to auto.
  • [ auto-flow && dense? ] <grid-auto-rows>? / <grid-template-columns>
    • sets grid-template-columns to the specified value.
    • If the auto-flow keyword is to the left of the slash, it sets grid-auto-flow to row.
    • If the dense keyword is specified additionally, the auto-placement algorithm uses a “dense” packing algorithm.
    • If grid-auto-rows is omitted, it is set to 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;
}

更复杂的用法:

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

Properties for the Children (Grid Items)

caution

float, display: inline-block, display: table-cell, vertical-aligncolumn-* 属性在网格单元内将不起作用!

grid-column- grid-row-

grid-column-start grid-column-end grid-row-start grid-row-end

通过参考特定的网格线来确定网格项在网格中的位置。
grid-column-start/grid-row-start 是项目开始的列/行,grid-column-end/grid-row-end 是项目结束的列/行。

Values:
  • <line> – 行/列数,或者行/列名字
  • span <number> – 该项目将跨越提供的网格轨道数量
  • span <name> – 该项目将跨越直到提供的名称的下一行
  • auto – 表示自动放置、自动跨度或默认跨度为 1

例子:

.item1 {
grid-column-start: 2;
grid-column-end: five;
grid-row-start: row1-start;
grid-row-end: 3;
}

grid-cr-1

.item2 {
grid-column-start: 1;
grid-column-end: span col4-start;
grid-row-start: 2;
grid-row-end: span 2;
}

grid-cr-2

项目可以相互重叠。您可以使用 z-index 来控制它们的堆叠顺序。

grid-column grid-row

grid-columngrid-column-startgrid-column-end的简写, grid-rowgrid-row-startgrid-row-end的简写

Values

<start-line> / <end-line>

.item {
/* grid-column: <start-line> / <end-line> | <start-line> / span <value>; */
/* grid-row: <start-line> / <end-line> | <start-line> / span <value>; */
}

grid-area

为项目命名,以便它可以被使用 grid-template-areas 属性创建的模板引用。即指定网格项的位置
也可作为 grid-row-start + grid-column-start + grid-row-end + grid-column-end 的简写

Values:
  • <name> – a name of your choosing
  • <row-start> / <column-start> / <row-end> / <column-end> – can be numbers or named lines

例子:(指定名字来确定位置)

.item3 {
grid-area: header;
/* 该项位于 grid-template-area 的 header 位置 */
}

作为多个属性简写来指定位置:

.item3 {
grid-area: 1 / col4-start / last-line / 6;
/* 指定上下左右的位置 */
}

grid-area2.png

justify-self align-self place-self

指定单个网格项目的内联轴/块轴方向上的对齐方式。
place-selfjustify-selfalign-self 的缩写。(<align-self> / <justify-self>,注意 align-self 在前)

Values:
  • start
  • end
  • center
  • stretch默认值

Special Units & Functions

fr

你最终可能会在 CSS Grid 中使用很多小数单位,比如 1fr。它们本质上是指“剩余空间的一部分”。
类似于百分比,但是比百分比更好用!

.item {
grid-template-columns: 50px min-content 1fr;
}

Sizing Keywords

在调整行和列的大小时,您可以使用常用单位 px、rem、% 等,但也可用关键字:

  • min-content: 内容的最小尺寸。想象像“E pluribus unum”这样的一行文本,其最小内容可能是“pluribus”这个词的宽度。
  • max-content: 内容的最大尺寸。想象上面的句子,max-content 就是整个句子的长度。
  • auto: 这个关键字很像 fr 单位,只是它们在分配剩余空间时“输掉”了与 fr 单位大小的斗争。
  • fit-content: 使用可用空间,但不要少于 min-content,也不要超过 max-content。
  • 函数单位:
    • minmax() 它为长度设置了一个最小值和最大值。
    • min()
    • max()

repeat()

repeat() 函数可以节省一些输入,例如:

.item {
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;

/* easier: */
grid-template-columns: repeat(8, 1fr);

/* especially when: */
grid-template-columns: repeat(8, minmax(10px, 1fr));
}

但是 repeat() 与关键字结合时会变得更加花哨:

  • auto-fill:在一行中填充尽可能多的列,即使它们是空的。
  • auto-fit:将任何列适应空间。更喜欢扩展列来填充空间而不是空列。

This bears the most famous snippet in all of CSS Grid and one of the all-time great CSS tricks:

.item {
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

Subgrid

子网格是网格的一个非常有用的功能,它允许网格项目拥有自己的网格,该网格从父网格继承网格线。

目前仅 Firefox 和 safari 支持此功能

display: contents 也许是一个替代方案。

Fluid Columns

不借助媒体查询,使流动宽度的列在空间可用时分成或多或少的列

代码片段:

.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* This is better for small screens, once min() is better supported */
/* grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr)); */
gap: 1rem;
}

grid动画支持

依据 CSS Grid Layout Module Level 1 ,有5个grid属性支持(目前只有firefox全支持!其它浏览器大都只支持 gap ):

  • grid-gap, grid-row-gap, grid-column-gap
  • grid-template-columns, grid-template-rows

示例: css代码写在 custom.css 中:

.grid-learn1 {
display: grid;
grid-template-columns: repeat(3, 120px);
grid-template-rows: repeat(2, 120px);
justify-content: center;
gap: 20px;
transition: all 1s;
}
.grid-learn1-toggle {
grid-template-columns: repeat(3, 80px);
grid-template-rows: repeat(2, 80px);
gap: 10px;
}
Result
Loading...
Live Editor

扩展阅读