CSS3 Flex 布局研究

Flex快速上手

容器的属性和常用值

容器可以通过设置display属性为flex / inline-flex(行内 flex)来指定其为 flex 布局。

下面,将记录一下容器的属性和常用值,基本可以囊括大多数应用场景。

child_database

项目的属性和常用值

首先来看下项目元素上常用的 2 个属性,orderflex-grow

embed

child_database

其中,order很好理解,下面通过一个例子来展示flex-grow属性的妙用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
<head>
<style>
div {
display: flex;
}
span:nth-child(1) {
flex-grow: 1;
}
</style>
</head>
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
</html>

可以在浏览器中看到,第一个<span>标签由于设置了flex-grow: 1,它自动占据了父容器除了剩下两个<span>标签外的所有空间!

Flex缩放研究

经常会看到 flex: 1 1 的写法,其实它是缩写:

1
2
3
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;

flex-grow:放大比例

默认为 0,即有多余空间的时候,项目不放大。

如果所有项目均 flex-grow 为 1,那么会自动等分多余空间;如果有个 2,也按照比例等分。

flex-shrink:缩小比例

默认为 1,如果空间不够,项目自动缩小。

如果一个项目为 0,其他为 1,那么空间不足,为 0 的项目不缩小。

flex-basis:项目主轴空间

默认值是 auto。定义的是未缩放前,项目所占主轴空间。

可以指定百分比、 auto 、px

Flex常见应用场景

场景 ①:水平垂直居中

以上面的html结构为例,如果要让<div>中的元素水平垂直居中,只需要以下样式代码:

1
2
3
4
5
div {
display: flex;
justify-content: center;
align-items: center;
}

场景 ②:左右两侧布局,其中一侧宽度确定;另一侧宽度占满剩余空间,并且自动响应

我们要做的就是将自动响应的那一侧的元素的flex-grow属性设置为 1 即可。

场景 ③:栅栏布局系统

还是以上面的html结构为例,实现一个将屏幕等分为 12 列,3 个<span>标签分别占据屏幕宽度的:1/6、1/6 和 2/3。

1
2
3
4
5
6
7
8
9
span:nth-child(1) {
flex: 2;
}
span:nth-child(2) {
flex: 2;
}
span:nth-child(3) {
flex: 8;
}

和原来相比,flex实现的栅栏布局优点有两个:

  1. 不再局限于 12 列
  2. 不再需要计算宽度,也不需考虑宽度浮点数带来的误差

经常会看到 flex: 1 1 的写法,其实它是缩写:

1
2
3
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;

Flex的坑

在实现水平垂直居中的过程中,发现了flex布局仅仅影响容器的一级子元素。例如下面这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
<head>
<style>
.level1 {
display: flex;
align-items: center;
justify-content: center;
}
</style>
</head>
<body>
<div class="level1">
<div class="level2">
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</div>
</body>
</html>

level2 类就不是水平垂直居中的,因为水平垂直居中仅仅影响到了level2,而不会进一步向下”污染“更深级别的子元素的布局样式

如果要让 level2 也实现水平垂直居中,我们可以专门封装一个用于水平垂直居中的类,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
<head>
<style>
.center {
display: flex;
align-items: center;
justify-content: center;
}
</style>
</head>
<body>
<div class="level1 center">
<div class="level2 center">
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</div>
</body>
</html>