布局

概述

flex: 一维布局, 一次只能处理一个维度上的元素布局,一行或者一列。
grid:二维布局, 同时处理行和列上的布局,跨行跨列。

Grid

示例

实现如下布局:

代码:

1
2
3
4
5
6
7
8
<div class="wrapper">
<div class="large">海瑞</div>
<div class="middle">徐阶</div>
<div class="middle">高拱</div>
<div class="large">嘉靖</div>
<div class="middle">张居中</div>
<div class="middle">裕王</div>
</div>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.wrapper {
width: 100%;
height: 100%;

display: grid;
grid-gap: 1rem;
grid-template-columns: repeat(4, calc((100% / 4) - (3 / 4) * 1rem));
grid-template-rows: repeat(2, calc((100% / 2) - (1rem / 2)));
}
.large {
grid-row: span 2;
}
.middle {
grid-row: span 1;
}
.wrapper > div {
background: #f1f1f1;
}

网格容器Grid Container

定义
1
display: grid | inline-grid;
行列模板

track-size: a length, a percentage, or a fraction of the free space in the grid (the fr unit)
line-name: 网格线名称

1
2
grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
grid-template-columns: <track-size> ... | <line-name> <track-size> ...;

区块模板 area

每个区块是一个网格组合。用每个区块占领grid-template-rows/columns定义的网格位置 。
其中,区块(area)和网格线(line, eg. row1-start)分别代表两种不同的维度。

1
2
3
4
5
6
7
8
9
/* 调用区块名称, 其中 . 或 none 表示空位 */
grid-template-areas:
"<grid-area-name> | . | none | ..."
"..."
"...";


/* 为每个区块定义名称 */
grid-area: "<grid-area-name>"

隐式(默认)行列

当某个网格项,没有显式定义行列(属于显式定义之外的超出项),但也想设置默认网格项的行列值。

1
2
grid-auto-columns: <track-size> ...;
grid-auto-rows: <track-size> ...;

流排列

若没有显式指定网格项的排列方式,可以指定默认流向。(这个效果跟flex很像了)。

  • row:默认行流向。自动换行。
  • column:默认列流向。自动换列。
  • dense:【不推荐】后面的网格项 往前挤,占领前面的空位
1
grid-auto-flow: row | column | row dense | column dense
模板简写
grid-template

grid-templategrid-template-rows, grid-template-columns, grid-template-areas 的简写形式。

由于 grid-template 不能设置隐式的grid属性(grid-auto-columns, grid-auto-rows, and grid-auto-flow),因此推荐使用grid-*属性替代 grid-template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
grid-template: none | <grid-template-rows> / <grid-template-columns>; /* 先行/后列 */


grid-template:
[row1-start] "header header header" 25px [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;

/* 与下述等价,行列模板与区块模板分开处理即可 */

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

gridgrid-template-rows, grid-template-columns, grid-template-areas , 及 grid-auto-rows, grid-auto-columns, grid-auto-flow的简写形式。可以同时显式定义/隐式定义模板值。

间隔 gap

网格区域内部间隔,不包括网格容器的外边界。

1
2
3
4
grid-column-gap: <line-size>; /* 新版本 column-gap */
grid-row-gap: <line-size>; /* 新版本 row-gap */

grid-gap: <grid-row-gap> <grid-column-gap>; /* 新版本 gap */

对齐方式 align
1
2
3
4
5
6
7
8
9
/* 网格内部内容的align */
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
place-items: <align-items> / <justify-items>;

/* 网格的本身相对于其父容器的align */
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
place-content: <align-content> / <justify-content>;
网格线名称 line

部分示例:

[first]
[line2]
[col4-start]
[five]
[end]

[row1-start]
[row1-end]]
[third-line]
[last-line]
[row2-end]

[row1-end row2-start]

网格项Grid Items

在网格项中,以下属性失效:

  • float
  • display: inline-block
  • display: table-cell
  • vertical-align
  • column-*
行列位置

基于line取值(从第几个到第几个网格线):

  1. number: a number of grid line
  2. name: a name of grid line
  3. span <name>: 从当前开始,到名称为name的 line 结束。

基于track取值(共几个网格):

  1. span <number>: across number of grid tracks

默认span = 1,即跨一个网格项

1
2
3
4
5
6
7
8
9
10
11
12
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;

/* 行简写 列简写 */
grid-column: <start-line> / <end-line> | <start-line> / span <value>;
grid-row: <start-line> / <end-line> | <start-line> / span <value>;

/* 行列简写, 区块名称 */
grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
对齐方式 align
1
2
3
justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;
place-self: <align-self> / <justify-self>;
叠加

z-index #控制网格项的叠加顺序

order #顺序

特殊值

repeat #重复若干次,eg: repeat(6, 1fr), repeat(3, 20px [col-start]);

fr #网格容器剩余空间等分

单位:px, rem, %, min-content, max-content, auto, fr等,混合亦可。

参考

[1]grid布局游戏
[2]5分钟学会 CSS Grid 布局
[3]CSS-TRICKS A Complete Guide to Grid

Flex

示例

实现如下布局:

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.wrapper {
width: 100%;
height: 100%;

display: flex;
flex-direction: rows;
flex-wrap: wrap;
}
.large {
flex: 3;
}
.middle {
flex: 2;
}
.wrapper > div {
border: 1px solid #ccc;
background: #f1f1f1;
}
.wrapper > div:not(:nth-last-of-type(1)) {
margin-right: 1rem;
}

垂直居中,且出现垂直滚动条

如上图图例,实现如下效果:

  1. 内容较少,无滚动条时,图例垂直居中
  2. 内容较多,出现滚动条
错误示例-flex

如下方式,只能实现垂直居中;当出现滚动条时,会吞掉顶部数据。
when the flex item overflows the container, the top becomes inaccessible.

justify-content: safe center; 其中,safe是flex用来解决overflow问题的,但基本不支持任何主流浏览器

1
2
3
4
5
<div class="wrapper">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
1
2
3
4
5
6
7
8
9
10
.wrapper {
display: flex;
flex-direction: column;
justify-content: safe center; /* attention */

height: 200px;
overflow: hidden;
overflow-y: auto;
}
.item {}
解决示例-margin:auto

用flex包裹一个子元素,使得该子元素margin:auto 居中(一种变通解决方案workaround)

1
2
3
4
5
6
7
<div class="wrapper">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>

1
2
3
4
5
6
7
8
9
10
11
.wrapper {
display: flex;
flex-direction: column;

height: 200px;
overflow: hidden;
overflow-y: auto;
}
.items {
margin: auto; /* attention */
}

也许是flex的核心理念就在于有缩放特点的弹性布局,而不愿在弹性布局之上出现滚动条(破坏缩放)。

参考

[1]Can’t scroll to top of flex item that is overflowing container

-------------Keep It Simple Stupid-------------
0%