grid布局学习笔记
Learn From:
Grid Properties for the Parent (Grid Container)
display
grid
– 生成一个块 grid 布局inline-grid
– 生成一个内联 grid 布局
.container {
/* */
display: grid;
/* */
/* display: inline-grid; */
}
grid-template-columns 和 grid-template-rows
使用空格分隔的值列表定义网格的列和行。这些值表示轨道大小,它们之间的间距表示网格线。
<track-size>
– 可取 数据值、百分值以及 fr
(free 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 是最后一行)。
另外,还可以选择显式命名这些行/列,但名字需要加上中括号 []
:
.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]
}
每个行/列可以有多个名字,名字之间加上空格即可:
.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
属性指定的网格区域名称来设置位置。
重复网格区域的名称会导致内容跨越这些单元格。
语法本身提供了网格结构的可视化。
<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
声明中的每一行都需要具有相同数量的单元格。
可以使用任意数量的 .
来声明单个空单元格。只要之间没有空格,它们就表示单个单元格。
这种方法只能给每个 网格区域 命名,而不能给 网格线 取名。
当您使用此语法时,区域两端的行实际上会自动命名。
如果网格区域的名称为 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
指定网格线的大小。您可以将其视为设置列/行之间的间隔的宽度。
<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;
}
*-gap
规定的是网格区域间行/列的间隔,并不影响与外部的元素间隔。
grid-*
前缀将被删除,grid-column-gap
和 grid-row-gap
重命名为 column-gap
和 row-gap
。
Chrome 68+、Safari 11.2 Release 50+ 和 Opera 54+ 已经支持无前缀属性。
gap grid-gap
row-gap
和column-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-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.
stretch
– 填充单元格的整个高度(默认值),(在网格单元没有设置宽高的情况下!)start
– 网格单元位于纵轴的开始位置end
– 网格单元位于纵轴的结束位置center
– 网格单元位于纵轴的中心位置baseline
– 沿文本基线对齐项目。基线有修饰符 —— 第一个基线和最后一个基线,在多行文本的情况下,它们将使用第一行或最后一行的基线。
可以在单个网格单元中通过 align-self
属性来设置对齐方式。
还有修饰符关键字 safe
和 unsafe
。用法就像 align-items: safe end
。
safe
关键字的意思是“尝试像这样对齐,但不会使其移动到无法访问的溢出区域”,
而 unsafe
将允许将内容移动到无法访问的区域(可能会导致数据丢失)。
place-items
place-items
是align-items
和justify-items
的简写
<align-items>
/ <justify-items>
– 注意第一个值是 align-items
!
如果省略第二个值,则将第一个值分配给两个属性。
这对于快速定位元素到中心非常有用:
.center {
display: grid;
place-items: center;
}
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).
- start – 网格位于网格容器的开始位置
- end – 网格位于网格容器的结束位置
- center – 网格位于网格容器的中心位置
- stretch – 改变网格项目,允许网格填充整个网格容器(水平方向,即填充所有宽度)(
grid-template-rows
的值有为auto
是才有用!) - space-around – 在每个网格项目之间放置均匀的空间,在远端有一半大小的空间
- space-between – 在每个网格项目之间放置均匀的空间,远端没有空间
- space-evenly – 在每个网格项目之间放置均匀的空间,包括远端
align-content
此属性设置沿块(列)轴对齐网格。
取值与justify-content
相同!注意:-
stretch
属性 只有当grid-template-columns
的值有为auto
或者不设定该属性时才有用!
place-content
place-content
是align-content
和justify-content
的简写
<align-content>
/ <justify-content>
– 第一个值设定 align-content
!第二个值设定 justify-content
!
如果省略第二个值,则将第一个值分配给两个属性。
grid-auto-columns grid-auto-rows
指定任何自动生成的网格轨迹(又名隐式网格轨迹 implicit grid tracks )的大小。 当网格项多于网格中的单元格或网格项放置在显式网格之外时,会创建隐式轨道。
拓展:The Difference Between Explicit and Implicit Grids)
<track-size>
– can be a length, a percentage, or a fraction of the free space in the grid (using the fr unit)
例子:
以上,我们将第二个网格项设置为从第 5 列开始,到第 6 列结束,但我们从未定义第 5 或 6 列。
因为我们引用了不存在的行,所以会创建宽度为 0 的隐式轨道来填充在缝隙中。
我们可以使用 grid-auto-columns
和 grid-auto-rows
来指定这些隐式轨道的宽度:
.container {
grid-auto-columns: 60px;
}
grid-auto-rows
同理!
grid-auto-flow
如果您有未明确放置在网格上的网格项目,则自动放置算法会启动以自动放置这些项目。
此属性控制自动放置算法的工作方式。
row
– 告诉自动放置算法依次填充行,并根据需要添加新行(默认值)column
– 优先列dense
– 尝试在网格中更早地填充
.container {
/* grid-auto-flow: row | column | row dense | column dense; */
}
请注意,dense
只会更改项目的视觉顺序,并可能导致它们出现乱序,这不利于可访问性。
grid
是
grid-template-rows
,grid-template-columns
,grid-template-areas
,grid-auto-rows
,grid-auto-columns
, 和grid-auto-flow
的简写
- 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)
float
, display: inline-block
, display: table-cell
, vertical-align
和 column-*
属性在网格单元内将不起作用!
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 是项目结束的列/行。
<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;
}
.item2 {
grid-column-start: 1;
grid-column-end: span col4-start;
grid-row-start: 2;
grid-row-end: span 2;
}
项目可以相互重叠。您可以使用 z-index
来控制它们的堆叠顺序。
grid-column grid-row
grid-column
是grid-column-start
和grid-column-end
的简写,grid-row
是grid-row-start
和grid-row-end
的简写
<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
的简写
<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;
/* 指定上下左右的位置 */
}
justify-self align-self place-self
指定单个网格项目的内联轴/块轴方向上的对齐方式。
place-self
是justify-self
和align-self
的缩写。(<align-self> / <justify-self>
,注意align-self
在前)
- 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;
}
扩展阅读
- The Difference Between Explicit and Implicit Grids
- Exploring CSS Grid’s Implicit Grid and Auto-Placement Power
- You want minmax(10px, 1fr) not 1fr
- Auto-Sizing Columns in CSS Grid:
auto-fill
vsauto-fit
- Native CSS Masonry Layout In CSS Grid
- Flexible Grids
- Basic concepts of grid layout
- Relationship of grid layout to other layout methods