Flex|Flex的简单应用

参考Flex 布局教程:语法篇 - 阮一峰的网络日志 (ruanyifeng.com)

一、Flex 布局是什么?

全称为 “Flexible Box Layout”,即 “弹性盒布局”,旨在提供一种更有效的方式来布局、对齐和分配容器中项目之间的空间,即使它们的大小未知或动态变化

容器里面包含着项目元素,使用 display:flexdisplay:inline-flex 声明为弹性容器

任何一个容器(包括行内元素)都可以指定为 Flex 布局。

1
2
3
4
5
6
.container{
display: flex;
}
.container{
display: inline-flex;
}

Webkit 内核的浏览器,必须加上-webkit前缀。

1
2
3
4
.container{
display: -webkit-flex; /* Safari */
display: flex;
}

注意,设为 Flex 布局以后,子元素的floatclearvertical-align属性将失效。

二、flex基本概念

1、容器与项目

采用 Flex 布局的元素(父元素),称为 Flex 容器(container),简称”容器”。它的所有容器内部的元素(子元素),称为 “项目”( item )

1
2
3
4
5
6
7
8
9
10
11
12

.container{
display: flex;
}

<div class="container">
<div class="item"> </div>
<div class="item">
<p class="sub-item"> </p>
</div>
<div class="item"> </div>
</div>

上面代码中, 最外层的div就是容器,内层的三个div就是项目。

注意:项目只能是容器的顶层子元素(直属子元素),不包含项目的子元素,比如上面代码的 p 元素就不是项目。flex布局只对项目生效。

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end

项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size

2、容器属性

  1. flex-direction 主轴方向
  2. flex-wrap 主轴一行满了换行
  3. flex-flow 1和2的组合
  4. justify-content 主轴元素对齐方式
  5. align-items 交叉轴元素对齐方式//单行
  6. align-content 交叉轴行对齐方式//多行

2.1主轴方向 flex-direction

定义主轴的方向,也就是子项目元素排列的方向

  • row (默认):从左到右 ltr ;从右到左 rtl
  • row-reverse :从右到左 ltr ;从左到右 rtl
  • column: 相同, row 但从上到下
  • column-reverse: 相同, row-reverse 但从下到上
1
2
3
.container {
flex-direction: row | row-reverse | column | column-reverse;
}

2.2换行 flex-wrap

设置子容器的换行方式,默认情况下,子项目元素都将尝试适合一行 nowrap

  • nowrap (默认)不换行
  • wrap 一行放不下时换行
  • wrap-reverse 换行,从下到上
1
2
3
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}

2.3简写 flex-flow

flex-direction flex-wrap 属性的简写,默认值为 row nowrap

1
2
3
.container {
flex-flow: column wrap;
}

2.4项目群对齐 justify-content

justify-content 决定子元素在主轴方向上的对齐方式,默认是 flex-start

  • flex-start(默认):左对齐
  • flex-end:右对齐
  • center: 居中
  • space-between:两端对齐,项目之间的间隔都相等。
  • space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
1
2
3
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;
}

2.5项目群对齐align-items

align-items 决定子元素在交叉轴方向上的对齐方式,默认是 stretch

  • flex-start:交叉轴的起点对齐。
  • flex-end:交叉轴的终点对齐。
  • center:交叉轴的中点对齐。
  • baseline: 项目的第一行文字的基线对齐。
  • stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
1
2
3
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;
}

2.6多行对齐 align-content

当容器内有多行时,align-content 定义多行的对齐方式(即定义了多根轴线,若只有一根轴线不起作用)

  • flex-start:与交叉轴的起点对齐。
  • flex-end:与交叉轴的终点对齐。
  • center:与交叉轴的中点对齐。
  • space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
  • space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
  • stretch(默认值):轴线占满整个交叉轴。
1
2
3
.container {
align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe;
}

2.7、间距 gap row-gap column-gap

gap 属性是用来设置网格行与列之间的间隙,该属性是 row-gapcolumn-gap 的简写形式。

1
2
3
4
5
6
7
8
.container {
display: flex;
...
gap: 10px;
gap: 10px 20px; /* row-gap column gap */
row-gap: 10px;
column-gap: 20px;
}

gap (grid-gap) - CSS:层叠样式表 | MDN (mozilla.org)

3、项目属性

  1. order 排序
  2. flex-grow 弹性成长
  3. flex-shrink 缩小
  4. align-self 覆盖container 的 align-items 属性
  5. flex-basis 宽度
  6. flex 简写

3.1 order排序

order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。

1
2
3
.item1 {
order: -1; /* default is 0 */
}

3.2 flex-grow 弹性成长

flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。

1
2
3
4
5
div:nth-of-type(1) {flex-grow: 1;}
div:nth-of-type(2) {flex-grow: 3;}
div:nth-of-type(3) {flex-grow: 1;}
div:nth-of-type(4) {flex-grow: 2;}
div:nth-of-type(5) {flex-grow: 1;}

3.3 flex-shrink 弹性缩小

flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

1
2
3
4
5
6
7
.ABC  { 
flex-shrink: 0;
}

.DE {
flex-shrink: 10;
}
  1. 如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
  2. 负值对该属性无效。

3.4 align-self 覆盖container 的 align-items 属性

align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch

3.5 flex-basis 宽度

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

3.6 flex 简写

flex属性是flex-grow, flex-shrinkflex-basis的简写,默认值为0 1 auto。后两个属性可选。

4、项目实战

要求:各部分占屏幕各1/4 放大、缩小、窗口拉伸自适应。

效果如下图

代码示例:

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
47
48
49
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Echarts弹性布局实战</title>
<style>
html,
body {
height: 100%;
margin: 0;
padding: 0;
}

.content {
height: 100%;
}

.boxs {
display: flex;
height: 50%;
}

.box {
border: 1px solid black;
width: 50%;
height: 100%;
}
</style>
</head>

<body>
<div class="content">
<div class="boxs">
<div class="box one"></div>
<div class="box two"></div>
</div>
<div class="boxs">
<div class="box three"></div>
<div class="box four">
</div>
</div>
</div>
<script src="/js/echarts.min.js"></script>
<script src="class1.js"></script>
</body>

</html>
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
//柱状图模块
(function () {
//1.实例化对象
var myChart = echarts.init(document.querySelector(".boxs .one"));
//2.指定配置项和数据
var option = {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data: ['销量']
},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}
]
};
//3.把配置项给实例对象
myChart.setOption(option);
// 4. 让图表跟随屏幕自动的去适应
window.addEventListener("resize", function () {
myChart.resize();
});
})();

// 折线图模块
(function () {
var myColor = ["#1089E7", "#F57474", "#56D0E3", "#F8B448", "#8B78F6"];
// 1. 实例化对象
var myChart = echarts.init(document.querySelector(".boxs .two"));
// 2. 指定配置和数据
var option = {
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
areaStyle: {}
}
]
};
// 3. 把配置给实例对象
myChart.setOption(option);
// 4. 让图表跟随屏幕自动的去适应
window.addEventListener("resize", function () {
myChart.resize();
});
})();

// 饼图模块制作
(function () {
//1.实例化对象
var myChart = echarts.init(document.querySelector(".boxs .three"));
//2.指定配置项和数据
var option = {
title: {
text: 'Nightingale Chart',
subtext: 'Fake Data',
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
left: 'center',
top: 'bottom',
data: [
'rose1',
'rose2',
'rose3',
'rose4',
'rose5',
'rose6',
'rose7',
'rose8'
]
},
toolbox: {
show: true,
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
restore: { show: true },
saveAsImage: { show: true }
}
},
series: [
{
name: 'Radius Mode',
type: 'pie',
radius: [20, 140],
center: ['25%', '50%'],
roseType: 'radius',
itemStyle: {
borderRadius: 5
},
label: {
show: false
},
emphasis: {
label: {
show: true
}
},
data: [
{ value: 40, name: 'rose 1' },
{ value: 33, name: 'rose 2' },
{ value: 28, name: 'rose 3' },
{ value: 22, name: 'rose 4' },
{ value: 20, name: 'rose 5' },
{ value: 15, name: 'rose 6' },
{ value: 12, name: 'rose 7' },
{ value: 10, name: 'rose 8' }
]
},
{
name: 'Area Mode',
type: 'pie',
radius: [20, 140],
center: ['75%', '50%'],
roseType: 'area',
itemStyle: {
borderRadius: 5
},
data: [
{ value: 30, name: 'rose 1' },
{ value: 28, name: 'rose 2' },
{ value: 26, name: 'rose 3' },
{ value: 24, name: 'rose 4' },
{ value: 22, name: 'rose 5' },
{ value: 20, name: 'rose 6' },
{ value: 18, name: 'rose 7' },
{ value: 16, name: 'rose 8' }
]
}
]
};
//3.把配置项给实例对象
myChart.setOption(option);
// 4. 让图表跟随屏幕自动的去适应
window.addEventListener("resize", function () {
myChart.resize();
});
})();
// 雷达图 模块制作
(function () {
//1.实例化对象
var myChart = echarts.init(document.querySelector(".boxs .four"));
//2.指定配置项和数据
var option = {
title: {
text: 'Basic Radar Chart'
},
legend: {
data: ['Allocated Budget', 'Actual Spending']
},
radar: {
// shape: 'circle',
indicator: [
{ name: 'Sales', max: 6500 },
{ name: 'Administration', max: 16000 },
{ name: 'Information Technology', max: 30000 },
{ name: 'Customer Support', max: 38000 },
{ name: 'Development', max: 52000 },
{ name: 'Marketing', max: 25000 }
]
},
series: [
{
name: 'Budget vs spending',
type: 'radar',
data: [
{
value: [4200, 3000, 20000, 35000, 50000, 18000],
name: 'Allocated Budget'
},
{
value: [5000, 14000, 28000, 26000, 42000, 21000],
name: 'Actual Spending'
}
]
}
]
};
//3.把配置项给实例对象
myChart.setOption(option);
// 4. 让图表跟随屏幕自动的去适应
window.addEventListener("resize", function () {
myChart.resize();
});
})();