Flex 布局手册

RN 的界面呈现方式和 Android 大不一样,Android 使用的是 Java + XML,而 RN 则使用的 JSX,就连完整的 HTML 都没有 (´・Д・)」。就像 RN 一样,Flex 布局对我而言也是一个全新的概念,于是在网上搜集了一些 Flex 布局的相关资料,并整理出了这个手册。

传统的布局方案依赖于 display + position + float,它对于一些特殊布局非常不方便,如垂直居中就非常不容易实现。

2009 年,W3C 提出了一种新的布局方案——Flex 布局,可以简单完整的实现各种页面布局。目前,它已得到了所有浏览器的支持。

使用 Flex 布局

Flex 是 Flexible Box 的缩写,意为“弹性布局”。任何一个元素都可以指定为 Flex 布局。使用了 Flex 布局之后,子元素的 float, clear, vertical-align 属性都将失效。

  • 对于区块元素,可以使用 display: flex; 来指定 Flex 布局;
  • 对于内联元素,可以使用 display: inline-flex 来指定 Flex 布局;
1
2
3
4
5
6
7
8
div {
display: -webkit-flex; /* 用于兼容 Safari */
display: flex;
}

span {
display: inline-flex;
}

Flex 指定的元素可分为两种: Container(父元素) 和 Item(子元素)。

Container 的属性

每个 Container 中都存在两根相互垂直的轴:主轴(main axis)和交叉轴(cross axis)。

  • 主轴的开始位置叫 main start,结束位置叫 main end,子元素在主轴上的大小叫 main size。
  • 交叉轴的开始位置叫 cross start,结束位置叫 cross end,子元素在交叉轴上的大小叫 cross size。

flex-direction

flex-direction 决定了主轴的方向。

flex-direction 的值 说明
row 默认值,主轴为水平方向,起点在左端
row-reverse 主轴为水平方向,起点在右端
column 主轴为垂直方向,起点在上沿
column-reverse 主轴在垂直方向,起点在下沿

flex-direction

flex-wrap

flex-wrap 决定了 Item 的换行方式。

flex-wrap 的值 说明
nowrap 默认值,不换行
wrap 正向换行,从交叉轴的开始位置,排列到交叉轴的结束位置
wrap-reverse 反向换行,从交叉轴的结束位置开始,排列到交叉轴的开始位置

flex-wrap

flex-flow

flex-flow 是 flex-direction 和 flex-wrap 的简写形式。

1
2
3
.container {
flex-flow: <flex-direction> <flex-wrap>;
}

justify-content

justity-content 定义了 Flex Item 在主轴上的对齐方式。

justify-content 的值 说明
flex-start 默认值,和主轴的起始位置对齐
flex-end 和主轴的结束位置对齐
center 和主轴的中间位置对齐
space-between 和主轴的两端对齐,每两个 Item 之间的留有相等的间隔
space-around 每个 Item 两端的间隔相等

justify-content

align-items

align-items 定义了 Flex Item 在交叉轴上的对齐方式。

align-items 的值 说明
flex-start 和交叉轴的起始位置对齐
flex-end 和交叉轴的结束位置对齐
center 和交叉轴的中间位置对齐
baseline 让每个 Item 的第一行文字的基线对齐
space-around 默认值,如果没有设置 Item 在 交叉轴上的大小或者设为 auto,那么 Item 将在交叉轴上占满父控件

align-items

align-content

align-content 定义了整体的对齐方式。如果 item 只有一个轴线,那么该属性将不起作用。

align-content 的值 说明
flex-start 与交叉轴的起始位置对齐
flex-end 与交叉轴的结束位置对齐
center 与交叉轴的中间位置对齐
space-between 与交叉轴的两端对齐,每行 Item 之间的间隔相等
space-around 每行 Item 两端的间隔相等
stretch 默认值,每行 Item 之间不留间隔,并缩放直至占满整个交叉轴

align_content

Item 的属性

order

order 的值是一个整数,表示 Item 的排列顺序。

order 的值越小,排列越靠前,默认值为 0。

1
2
3
.item {
order: <integer>;
}

flex-grow

flow-grow 的值是一个整数,定义了 Item 的放大比例。默认为 0,即如果存在剩余空间,也进行放大。

1
2
3
.item {
flex-grow: <integer>;
}

flex-shrink

flex-shrink 的值也是一个整数,定义了 Item 的缩小比例。默认值为 1,即如果空间不足,该 Item 将被缩小。

flex-basis

flex-basis 定义了在分配多余空间之前,Item 占据的主轴空间大小(main size)。浏览器会根据 flex-basis 的值来计算主轴上是否有多余空间。默认值为 auto,即 Item 的原本大小。

flex-basis 类似于 width 和 height,会使 Item 占据固定的空间。

flex

flex 是 flex-grow, flex-shrink, flex-basis 的简写,默认值为0 1 auto

1
2
3
.item {
flex: {none | <flex-grow> <flex-shrink> <flex-basis>};
}

align-self

align-self 允许单个 item 与其他 item 拥有不一样的对齐方式。

align-self 可覆盖 container 的 align-items 属性的值。默认值为 auto,表示继承父类的 align-items 属性。

Sample

下面是测试时用的一个 Flex 布局示例,仅供参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!DOCTYPE HTML>
<html>
<head>
<title>Flext 布局</title>
<style type="text/css">
div.container {
background-color: #33ee33;
color: white;
height: 640px;

/* 设置为 flex 布局后,子元素的 flaat, clear, vertical-align 属性将失效 */
display: -webkit-flex; /* 为了兼容 Safari */
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: center; /* 主轴的对齐方式 */
align-items: flex-end; /* 交叉轴的对齐方式 */
align-content: center;
}
div.item {
background-color: #ee3333;
color: white;
margin: 8px;
padding: 8px;
width: 120px;
height: 120px;

order: 1;
/*flex-grow: 1;*/
}
</style>
</head>
<body>
<div class="container">
<h1>Container</h1>
<div class="item">Item1<br>Item1</div>
<div class="item" style="order: 0;">Item2 Item2</div>
<div class="item" >Item3</div>
<div class="item">Item4</div>
<div class="item">Item5</div>
<div class="item" style="flex-grow: 4;">Item6</div>
<div class="item">Item7</div>
<div class="item">Item8</div>
</div>
</body>
</html>

参考