CSS Grid布局
CSS Grid
给栅格容器设定 display: grid
或值为 inline-grid 后,其直接子元素就变为栅格 item。
栅格 item 通过设定 display 属性也可以成为栅格容器(实现 nesting grids)。
因为栅格布局优先,所以_float_ 、 clear 和 vertical-align 属性对于栅格 item 不起作用。
目前除 IE 浏览器,栅格布局在其他浏览器中都不需要 prefix,可以安全地使用。
与 Flex 布局的区别
- Grid 布局是一种二维布局系统,Flex用来实现一维空间布局,in a row / column
- 当 wrap flex 元素时,新的每一个行都变成一个新的 flex 容器,沿行所在的轴分配空间
- 当需要既沿 row 轴又沿 column 轴对齐元素时,就应该使用 Grid 布局
- Flex box:让内容的尺寸决定每个元素所占的单独空间
- Grid system:创建布局,然后把元素放上去
通过布局实现元素的 reordering 都是 visual(视觉上的),不会改变 text-to-speech、文档的 tab order 的逻辑顺序。
父元素的属性
Gird track 栅格轨道
栅格轨道是栅格上任意两条线之间的space。通过 grid-template-columns 和 grid-template-rows 定义列和行的宽度。
如此定义的栅格即为 explicit grid。
-
轨道尺寸可以设为 fixed,如以
px
为单位;可以是 flexible,以fr
为单位。单位fr
表示栅格容器里可用空间的一个 fraction(片段)。grid-template-columns: 500px 1fr 2fr;
- 同时使用固定单位和 flexible 单位时,先从可用空间里减去固定宽度,再根据所占比例划分剩余空间。
-
定义大型栅格多条轨道时,可使用
repeat(重复次数, 重复pattern)
实现重复全部或部分track列表。如:grid-template-columns: repeat(3, 33.33%); // 3列,每列33.33%宽 grid-template-rows: repeat(2, 50px); // 2行,每行50px高
auto-fill vs. auto-fit
看视频:
implicit grid 未明确设定大小的栅格
如果内容被放置在 defined grid 之外,则会创建隐含的 gird。
- 隐含轨道默认是 auto-sized,其尺寸基于所含内容
- 通过 grid-auto-rows 和 grid-auto-columns 来控制尺寸
- 使用
minmax(minVal, maxVal)
作为属性值可指定长度范围 - 该属性支持多值,如:
grid-auto-rows: 100px 200px;
, 表示 repeat 模式,一行100px高,下一行200px高,交叉重复。(FF不支持) - 通过
grid-column-end: span 2;
扩展关键字,即使使用明确定位属性,仍然可以利用自动摆放
Auto placement 自动摆放规则
默认地,每个子元素沿 row 轴根据在 document source 中的书写顺序(同时也是 DOM order)填入到一个栅格 cell 中。
- 如果 explicit 栅格没有足够的行放置,则自动创建 implicit 行来放
- 先把明确定位的 item 放好,再按照书写顺序依次摆放剩下的元素
- 当一行所剩空间放不下 item 时,移到下一行找地方放
- 没有写在任何标签里的内容将成为 anonymous 栅格 item,匿名栅格元素总是自动放置
通过 grid-auto-flow: column;
改变放置方向为沿 column 轴,该属性也支持多值。
只给部分元素明确定位会导致栅格上有许多 holes,如果希望尽可能填满,则 grid-auto-flow: dense;
,遇到合适的就补上去。
Gutters 间隙
栅格单元格之间的空隙/间距,通过 grid-column-gap 和 grid-row-gap 属性创建(缩写属性为 grid-gap)。
- gap 所占据的空间在计算弹性长度
fr
时,先从可用空间里减去 - 空隙里不能放任何东西
- 只出现在栅格 tracks 之间,不会出现在栅格上下左右边界
Grid areas
通过使用 grid-template-areas 属性,就不需要在子元素上设置具体的定位数据。
grid-template-areas:
"hd hd hd hd hd hd hd hd hd"
"sd sd sd main main main main main main"
". . . ft ft ft ft ft ft";
- 其中
.
表示一个空的栅格cell - 栅格 area 名称前后可以有任意个 white space,便于代码对齐
- 该属性的值必须是完整的栅格,即每行 cell 的个数必须相同
Alignment 对齐
- 通过 align-items 设置 grid area 中的元素在 block/column 轴上对齐的方式。
- 通过 justify-items 设置 grid area 中的元素在 inline/row 轴上对齐的方式。
- 合并简写形式为
place-items: <align> / <justify>;
当栅格 track 占据的区域比栅格容器小时,可以通过 align-content 和 justify-content 设置栅格的整体内容在 column/row 轴的对齐方式。
两个属性值默认都是 start
,即把有内容的栅格区域放置在左上角。
子元素的属性
Grid lines 栅格线
默认地,当我们定义栅格时,只是定义了 grid track,栅格系统会自动产生以数字为编号的栅格线。
栅格线编号从1开始,自增顺序根据文档的书写模式(从左到右或从右到左)。
通过 grid-column-start, grid-column-end, grid-row-start 和 grid-row-end 属性来放置元素。
- 这些属性的值为具体的 line 编号/名称。
- 当不指定终点 gird-*-end 时,默认扩展一列/行。
- 没有明确定位的栅格 item 将根据 auto-placement 算法,摆放进栅格系统的空余地方。
- 缩写形式为
grid-column: <line> / <line>;
,grid-row 同。 - 使用 span 关键字,指定轨道要扩展的行/列个数。
- 值为0无效
- 值为负整数,表示 reverse,从栅格的 end edge 开始。
named lines
grid-template-columns: [main-start] 1fr [content-start] 1fr [content-end] 1fr [main-end];
使用 named lines 来定位栅格item:
- 不需要给所有的栅格线命名(没命名的还是默认数字编号)
- 同一条线可以有多个名称,即 line name 方括号支持以空格分隔的多个值
- line 名称以
-start
和-end
结尾,会创建同名的 implicit grid area - 反之亦然,named template area 也默认创建命名式的 line
grid-column: test
,将使用名称为test的 named grid area 的起始/截止边作为栅格线
好处:在 responsive design 中,当重新定义栅格时,不需要在 media query 里改变子元素定位用的 line number。
不建议使用 repeat()
创建多个同名 line,用起来不直观,还增加代码量。
Grid cells
是栅格系统的最小单位,就如表格的单元格。
- 栅格 item 可以占据相同的 cell,因此可以 overlap
- 通过定义 z-index 控制层叠顺序
- 默认代码书写顺序在后面的显示在上层
Grid areas
栅格元素可以在行或列上扩展占据一个或多个cell,如此产生了 grid area。
- 栅格区域必须是矩形的
- 行/列定位进一步可缩写为
grid-area: <row-start-line> / <column-start-line> / <row-end-line> / <column-end-line>;
- grid-area 属性值也可以是 string 表示的名称,该用法需要在父元素(grid container)中配合使用 grid-template-areas 属性
Alignment 对齐
通过 align-self 设置 grid area 中的单个元素在 block/column 轴上对齐的方式。
通过 justify-self 设置单个元素在 inline/row 轴上的对齐。
默认表现为 stretch,即不明确设置就占满栅格区域。
还可以使用 auto margin 来消耗掉所有可用空间来实现对齐,如 margin:auto;
实现子元素在栅格 area 内中心居中。
Absolutely positioned
当 grid 容器元素为 relatively positioned 时,在子元素上设置 position: absolute
,实现效果为:
子元素先根据指定的行和列(定位、扩展宽高)放置,然后使用 top、left 等属性进行位移。由于该元素脱离了文档流,其宽高仍然限制在栅格线之间,但不会产生额外的行和列。
当 grid 容器元素没有创造一个 positioning context 时,相对放置的子元素就不再被栅格布局所限制了。