Flex弹性布局
一、简介
Flexible box旨在提供一个更加有效的方式来布局在容器之间的各项内容,即使它们的大小是未知或者动态变化的。
传统的布局方案是基于盒(box)模型,通过display、position和float属性来实现布局,这种布局方式比较简单,但是对于某些特殊的布局是很不方便 的,譬如在一个不确定高度的div中实现图片的垂直居中。
2009年,W3C提出了一种新的方案----Flex布局,可以简便、完整、响应式地实现各种页面布局,旨在提供一个更加有效的方式来布置,对齐和分布在容器之间的各项内容,即使它们的大小是未知或者动态变化的。来看一下各个浏览器对该属性的支持情况:
二、基本概念
Flex(Flexible Box)意为弹性盒子,采用Flex布局的元素称为Flex容器,简称“容器”,其子元素为容器的成员,称为Flex项目,简称“项目”。任何元素都可以使用FLex布局,指定Flex布局之后,其所有子元素的float、clear以及vertical-align属性将会失效。来看一下Flex容器的样子:
三、属性设置
先看一下有那些属性:
-
flex-direction
-
flex-wrap
-
flex-flow
-
justify-content
-
align-items
-
align-content
-
order
1、flex-direction
该属性通过定义flex容器的主轴方向来决定felx子项在flex容器中的位置。这将决定flex需要如何进行排列
flex-direction:row | row-reverse | column | column-reverse
row:主轴与行内轴方向作为默认的书写模式。即横向从左到右排列(左对齐)。
row-reverse:对齐方式与row相反。
column:主轴与块轴方向作为默认的书写模式。即纵向从上往下排列(顶对齐)。
column-reverse:对齐方式与column相反。
1 <div class="wrap">
2 <div id="box1" class="flex">
3 <div class="item">1</div>
4 <div class="item">2</div>
5 <div class="item">3</div>
6 </div>
7 <div id="box2" class="flex">
8 <div class="item">1</div>
9 <div class="item">2</div>
10 <div class="item">3</div>
11 </div>
12 <div id="box3" class="flex">
13 <div class="item">1</div>
14 <div class="item">2</div>
15 <div class="item">3</div>
16 </div>
17 <div id="box4" class="flex">
18 <div class="item">1</div>
19 <div class="item">2</div>
20 <div class="item">3</div>
21 </div>
22 </div>
1 .flex {
2 width: 800px;
3 display: flex;
4 background-color: #732;
5 border-bottom: 3px solid #fff;
6 }
7 .flex .item {
8 width: 60px;
9 height: 60px;
10 margin: 5px 10px;
11 line-height: 60px;
12 text-align: center;
13 color: #000;
14 font-weight: bold;
15 font-size: 18px;
16 background-color: #0AF0D4;
17 }
18 #box1 {
19 flex-direction: row;
20 }
21 #box2 {
22 flex-direction: row-reverse;
23 }
24 #box3 {
25 flex-direction: column;
26 }
27 #box4 {
28 flex-direction: column-reverse;
29 }
运行结果如下:
2、flex-wrap
该属性控制flex容器是单行或者多行,同时横轴的方向决定了新行堆叠的方向
flex-wrap: nowrap | wrap | wrap-reverse;
nowrap 默认值。规定灵活的项目不拆行或不拆列。(flex容器为单行。该情况下flex子项可能会溢出容器)
wrap 规定灵活的项目在必要的时候拆行或拆列。(flex容器为多行。该情况下flex子项溢出的部分会被放置到新行,子项内部会发生断行)
wrap-reverse 规定灵活的项目在必要的时候拆行或拆列,但是以相反的顺序。
1 <div class="wrap">
2 <div id="box1" class="flex">
3 <div class="item">1</div>
4 <div class="item">2</div>
5 <div class="item">3</div>
6 </div>
7 <div id="box2" class="flex">
8 <div class="item">1</div>
9 <div class="item">2</div>
10 <div class="item">3</div>
11 </div>
12 <div id="box3" class="flex">
13 <div class="item">1</div>
14 <div class="item">2</div>
15 <div class="item">3</div>
16 </div>
17 </div>
1 .flex {
2 width: 300px;
3 padding: 10px;
4 display: flex;
5 background-color: #732;
6 border-bottom: 3px solid #fff;
7 }
8 .flex .item {
9 width: 100px;
10 height: 100px;
11 margin: 5px;
12 border: 3px solid #fff;
13 line-height: 100px;
14 text-align: center;
15 color: #000;
16 font-weight: bold;
17 font-size: 18px;
18 background-color: #0AF0D4;
19 }
20 #box1 {
21 flex-wrap: nowrap;
22 }
23 #box2 {
24 flex-wrap: wrap;
25 }
26 #box3 {
27 flex-wrap: wrap-reverse;
28 }
运行结果如下:
3、flex-flow
复合属性。设置或检索弹性盒模型对象的子元素排列方式。
flex-flow: flex-direction | flex-wrap
4、justify-content
设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式,当弹性盒里一行上的所有子元素都不能伸缩或已经达到其最大值时,这一属性可协助对多余的空间进行分配。当元素溢出某行时,这一属性同样会在对齐上进行控制
justify-content:flex-start | flex-end | center | space-between | space-around
flex-start:弹性盒子元素将向行起始位置对齐。该行的第一个子元素的主起始位置的边界将与该行的主起始位置的边界对齐,同时所有后续的伸缩盒项目与其前一个项目对齐。
flex-end:弹性盒子元素将向行结束位置对齐。该行的第一个子元素的主结束位置的边界将与该行的主结束位置的边界对齐,同时所有后续的伸缩盒项目与其前一个项目对齐。
center:弹性盒子元素将向行中间位置对齐。该行的子元素将相互对齐并在行中居中对齐,同时第一个元素与行的主起始位置的边距等同与最后一个元素与行的主结束位置的边距(如果剩余空间是负数,则保持两端相等长度的溢出)。
space-between:弹性盒子元素会平均地分布在行里。如果最左边的剩余空间是负数,或该行只有一个子元素,则该值等效于'flex-start'。在其它情况下,第一个元素的边界与行的主起始位置的边界对齐,同时最后一个元素的边界与行的主结束位置的边距对齐,而剩余的伸缩盒项目则平均分布,并确保两两之间的空白空间相等。
space-around:弹性盒子元素会平均地分布在行里,两端保留子元素与子元素之间间距大小的一半。如果最左边的剩余空间是负数,或该行只有一个伸缩盒项目,则该值等效于'center'。在其它情况下,伸缩盒项目则平均分布,并确保两两之间的空白空间相等,同时第一个元素前的空间以及最后一个元素后的空间为其他空白空间的一半。
1 <div class="wrap">
2 <h3>justify-content: flex-start</h3>
3 <div id="box1" class="flex">
4 <div class="item">1</div>
5 <div class="item">2</div>
6 <div class="item">3</div>
7 </div>
8 <h3>justify-content: flex-end</h3>
9 <div id="box2" class="flex">
10 <div class="item">1</div>
11 <div class="item">2</div>
12 <div class="item">3</div>
13 </div>
14 <h3>justify-content: center</h3>
15 <div id="box3" class="flex">
16 <div class="item">1</div>
17 <div class="item">2</div>
18 <div class="item">3</div>
19 </div>
20 <h3>justify-content: space-between</h3>
21 <div id="box4" class="flex">
22 <div class="item">1</div>
23 <div class="item">2</div>
24 <div class="item">3</div>
25 </div>
26 <h3>justify-content: space-around</h3>
27 <div id="box5" class="flex">
28 <div class="item">1</div>
29 <div class="item">2</div>
30 <div class="item">3</div>
31 </div>
32 </div>
1 .flex {
2 width: 400px;
3 padding: 10px;
4 display: flex;
5 background-color: #732;
6 border-bottom: 3px solid #fff;
7 }
8 .flex .item {
9 width: 40px;
10 height: 60px;
11 margin: 5px;
12 border: 3px solid #fff;
13 line-height: 60px;
14 text-align: center;
15 color: #000;
16 font-weight: bold;
17 font-size: 18px;
18 background-color: #0AF0D4;
19 }
20 #box1 {
21 justify-content: flex-start;
22 }
23 #box2 {
24 justify-content: flex-end;
25 }
26 #box3 {
27 justify-content: center;
28 }
29 #box4 {
30 justify-content: space-between;
31 }
32 #box5 {
33 justify-content: space-around;
34 }
运行结果如下:
5、align-items
定义flex子项在flex容器的当前行的侧轴(纵轴)方向上的对齐方式。
align-items:flex-start | flex-end | center | baseline | stretch
flex-start:弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界。
flex-end:弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界。
center:弹性盒子元素在该行的侧轴(纵轴)上居中放置。(如果该行的尺寸小于弹性盒子元素的尺寸,则会向两个方向溢出相同的长度)。
baseline:如弹性盒子元素的行内轴与侧轴为同一条,则该值与'flex-start'等效。其它情况下,该值将参与基线对齐。
stretch:如果指定侧轴大小的属性值为'auto',则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照'min/max-width/height'属性的限制。
1 <div class="wrap">
2 <h3>align-items: flex-start</h3>
3 <div id="box1" class="flex">
4 <div class="item">1</div>
5 <div class="item">2</div>
6 <div class="item">3</div>
7 </div>
8 <h3>align-items: flex-end</h3>
9 <div id="box2" class="flex">
10 <div class="item">1</div>
11 <div class="item">2</div>
12 <div class="item">3</div>
13 </div>
14 <h3>align-items: center</h3>
15 <div id="box3" class="flex">
16 <div class="item">1</div>
17 <div class="item">2</div>
18 <div class="item">3</div>
19 </div>
20 <h3>align-items: baseline</h3>
21 <div id="box4" class="flex">
22 <div class="item">1</div>
23 <div class="item">2</div>
24 <div class="item">3</div>
25 </div>
26 <h3>align-items: stretch</h3>
27 <div id="box5" class="flex">
28 <div class="item">1</div>
29 <div class="item">2</div>
30 <div class="item">3</div>
31 </div>
32 </div>
1 .flex {
2 width: 300px;
3 padding: 3px;
4 display: flex;
5 background-color: #732;
6 border-bottom: 3px solid #fff;
7 }
8 .flex .item {
9 color: #000;
10 margin: 3px;
11 border: 3px solid #fff;
12 font-weight: bold;
13 text-align: center;
14 font-size: 18px;
15 background-color: #0AF0D4;
16 }
17 .flex .item:first-child {
18 padding: 10px 20px;
19 }
20 .flex .item:nth-child(2) {
21 padding: 15px 30px;
22 }
23 .flex .item:last-child {
24 padding: 35px 40px;
25 }
26 #box1 {
27 align-items: flex-start;
28 }
29 #box2 {
30 align-items: flex-end;
31 }
32 #box3 {
33 align-items: center;
34 }
35 #box4 {
36 align-items: baseline;
37 }
38 #box5 {
39 align-items: stretch;
40 }
运行结果如下:
6、align-content
当伸缩容器的侧轴还有多余空间时,本属性可以用来调准「伸缩行」在伸缩容器里的对齐方式,这与调准伸缩项目在主轴上对齐方式的 <' justify-content '> 属性类似。请注意本属性在只有一行的伸缩容器上没有效果。
align-content:flex-start | flex-end | center | space-between | space-around | stretch
flex-start:各行向弹性盒容器的起始位置堆叠。弹性盒容器中第一行的侧轴起始边界紧靠住该弹性盒容器的侧轴起始边界,之后的每一行都紧靠住前面一行。
flex-end:各行向弹性盒容器的结束位置堆叠。弹性盒容器中最后一行的侧轴起结束界紧靠住该弹性盒容器的侧轴结束边界,之后的每一行都紧靠住前面一行。
center:各行向弹性盒容器的中间位置堆叠。各行两两紧靠住同时在弹性盒容器中居中对齐,保持弹性盒容器的侧轴起始内容边界和第一行之间的距离与该容器的侧轴结束内容边界与第最后一行之间的距离相等。(如果剩下的空间是负数,则各行会向两个方向溢出的相等距离。)
space-between:各行在弹性盒容器中平均分布。如果剩余的空间是负数或弹性盒容器中只有一行,该值等效于'flex-start'。在其它情况下,第一行的侧轴起始边界紧靠住弹性盒容器的侧轴起始内容边界,最后一行的侧轴结束边界紧靠住弹性盒容器的侧轴结束内容边界,剩余的行则按一定方式在弹性盒窗口中排列,以保持两两之间的空间相等。
space-around:各行在弹性盒容器中平均分布,两端保留子元素与子元素之间间距大小的一半。如果剩余的空间是负数或弹性盒容器中只有一行,该值等效于'center'。在其它情况下,各行会按一定方式在弹性盒容器中排列,以保持两两之间的空间相等,同时第一行前面及最后一行后面的空间是其他空间的一半。
stretch:各行将会伸展以占用剩余的空间。如果剩余的空间是负数,该值等效于'flex-start'。在其它情况下,剩余空间被所有行平分,以扩大它们的侧轴尺寸。
1 <div class="wrap">
2 <h3>align-content: flex-start</h3>
3 <div id="box1" class="flex">
4 <div class="item">1</div>
5 <div class="item">2</div>
6 <div class="item">3</div>
7 <div class="item">4</div>
8 </div>
9 <h3>align-content: flex-end</h3>
10 <div id="box2" class="flex">
11 <div class="item">1</div>
12 <div class="item">2</div>
13 <div class="item">3</div>
14 <div class="item">4</div>
15 </div>
16 <h3>align-content: center</h3>
17 <div id="box3" class="flex">
18 <div class="item">1</div>
19 <div class="item">2</div>
20 <div class="item">3</div>
21 <div class="item">4</div>
22 </div>
23 <h3>align-content: space-between</h3>
24 <div id="box4" class="flex">
25 <div class="item">1</div>
26 <div class="item">2</div>
27 <div class="item">3</div>
28 <div class="item">4</div>
29 </div>
30 <h3>align-content: stretch</h3>
31 <div id="box5" class="flex">
32 <div class="item">1</div>
33 <div class="item">2</div>
34 <div class="item">3</div>
35 <div class="item">4</div>
36 </div>
37 <h3>align-content: space-around</h3>
38 <div id="box6" class="flex">
39 <div class="item">1</div>
40 <div class="item">2</div>
41 <div class="item">3</div>
42 <div class="item">4</div>
43 </div>
44 </div>
1 .flex {
2 width: 300px;
3 height: 130px;
4 padding: 3px;
5 display: flex;
6 flex-wrap:wrap;
7 background-color: #732;
8 border-bottom: 3px solid #fff;
9 }
10 .flex .item {
11 color: #000;
12 margin: 1px;
13 padding: 6px 30px;
14 border: 2px solid #fff;
15 font-weight: bold;
16 text-align: center;
17 font-size: 18px;
18 background-color: #0AF0D4;
19 }
20 #box1 {
21 align-content: flex-start;
22 }
23 #box2 {
24 align-content: flex-end;
25 }
26 #box3 {
27 align-content: center;
28 }
29 #box4 {
30 align-content: space-between;
31 }
32 #box5 {
33 align-content: stretch;
34 }
35 #box6 {
36 align-content: space-around;
37 }
运行结果如下:
7、order
用整数值来定义排列顺序,数值小的排在前面。可以为负值
1 <div id="box1" class="flex">
2 <div class="item">1</div>
3 <div class="item">2</div>
4 <div class="item">3</div>
5 <div class="item">4</div>
6 <div class="item">5</div>
7 </div>
1 .flex {
2 width: 500px;
3 height: 130px;
4 padding: 15px;
5 display: flex;
6 flex-wrap:wrap;
7 background-color: #732;
8 border-bottom: 3px solid #fff;
9 }
10 .flex .item {
11 margin: 1px;
12 padding: 6px 30px;
13 border: 2px solid #fff;
14 font-weight: bold;
15 text-align: center;
16 font-size: 18px;
17 background-color: #0AF0D4;
18 }
19 .item:nth-child(3) {
20 order: -1;
21 }
运行结果如下:
8、align-self
定义flex子项单独在侧轴(纵轴)方向上的对齐方式
align-self:auto | flex-start | flex-end | center | baseline | stretch
auto:如果'align-self'的值为'auto',则其计算值为元素的父元素的'align-items'值,如果其没有父元素,则计算值为'stretch'。
flex-start:弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界。
flex-end:弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界。
center:弹性盒子元素在该行的侧轴(纵轴)上居中放置。(如果该行的尺寸小于弹性盒子元素的尺寸,则会向两个方向溢出相同的长度)。
baseline:如弹性盒子元素的行内轴与侧轴为同一条,则该值与'flex-start'等效。其它情况下,该值将参与基线对齐。
stretch:如果指定侧轴大小的属性值为'auto',则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照'min/max-width/height'属性的限制。
1 <div class="wrap">
2 <div id="box1" class="flex">
3 <div class="item">1</div>
4 <div class="item">2</div>
5 <div class="item">3</div>
6 <div class="item">4</div>
7 <div class="item">5</div>
8 <div class="item">6</div>
9 </div>
10 </div>
1 .flex {
2 width: 300px;
3 height: 200px;
4 padding: 10px;
5 display: flex;
6 flex-wrap:wrap;
7 background-color: #732;
8 }
9 .flex .item {
10 margin: 1px;
11 padding: 10px;
12 border: 2px solid #fff;
13 font-weight: bold;
14 text-align: center;
15 background-color: #0AF0D4;
16 }
17 .item:nth-child(1) {
18 align-self: auto;
19 }
20 .item:nth-child(2) {
21 align-self: flex-start;
22 }
23 .item:nth-child(3) {
24 align-self: flex-end;
25 }
26 .item:nth-child(4) {
27 align-self: center;
28 }
29 .item:nth-child(5) {
30 align-self: baseline;
31 }
32 .item:nth-child(6) {
33 align-self: stretch;
34 }
运行结果如下:
9、flex-grow
设置或检索弹性盒的扩展比率,根据弹性盒子元素所设置的扩展因子作为比率来分配剩余空间。
1 <div class="wrap">
2 <div id="box1" class="flex">
3 <div class="item">1</div>
4 <div class="item">2</div>
5 <div class="item">3</div>
6 <div class="item">4</div>
7 <div class="item">5</div>
8 </div>
9 </div>
1 .flex {
2 width: 420px;
3 height: 120px;
4 padding: 10px;
5 display: flex;
6 flex-wrap:wrap;
7 background-color: #732;
8 }
9 .flex .item {
10 width: 50px;
11 height: 100px;
12 border: 2px solid #fff;
13 font-weight: bold;
14 text-align: center;
15 background-color: #0AF0D4;
16 }
17 .item:nth-child(2) {
18 flex-grow: 1;
19 }
20 .item:nth-child(3) {
21 flex-grow: 2;
22 }
运行结果如下:
10、flex-shrink
设置或检索弹性盒的收缩比率,根据弹性盒子元素所设置的收缩因子作为比率来收缩空间。
1 .flex {
2 width: 420px;
3 height: 120px;
4 padding: 10px;
5 display: flex;
6 background-color: #732;
7 }
8 .flex .item {
9 width: 100px;
10 height: 100px;
11 border: 2px solid #fff;
12 font-weight: bold;
13 text-align: center;
14 background-color: #0AF0D4;
15 }
16 .item:nth-child(2) {
17 flex-shrink: 2;
18 }
19 .item:nth-child(3) {
20 flex-shrink: 4;
21 }
运行结果如下:
11、flex-basis
设置或检索弹性盒伸缩基准值,如果所有子元素的基准值之和大于剩余空间,则会根据每项设置的基准值,按比率伸缩剩余空间。
1 .flex {
2 width: 420px;
3 height: 120px;
4 padding: 10px;
5 display: flex;
6 background-color: #732;
7 }
8 .flex .item {
9 width: 100px;
10 height: 100px;
11 border: 2px solid #fff;
12 font-weight: bold;
13 text-align: center;
14 background-color: #0AF0D4;
15 }
16 .item:nth-child(2) {
17 flex-basis: 200px;
18 }
19 .item:nth-child(3) {
20 flex-basis: 300px;
21 }
运行结果如下:
12、flex
复合属性。设置或检索弹性盒模型对象的子元素如何分配空间。
如果缩写「flex: 1」, 则其计算值为「1 1 0%」
如果缩写「flex: auto」, 则其计算值为「1 1 auto」
如果「flex: none」, 则其计算值为「0 0 auto」
如果「flex: 0 auto」或者「flex: initial」, 则其计算值为「0 1 auto」,即「flex」初始值