乐趣区

10分钟理解CSS3 FlexBox

基本介绍
特点

flexbox 是一种 css display 类型,提供一种更简单高效的布局方式;
flexbox 可以对元素相对于父元素、兄弟元素进行定位、控制尺寸、控制间距;
flexbox 对响应式有很好的支持;

工作原理
设置父元素的 display 属性为 flex,则子元素都变成 flex item,由此可以控制子元素的排列方式、尺寸、间距等;
兼容性

Flex Container
先来看一个最简单的 flex 示例,外层 div 设置 display: flex 成为一个 flex container,内部的 3 个 div 则自动变为 flex item:
html:
<div class=”flex-container”>
<div class=”box one”></div>
<div class=”box two”></div>
<div class=”box three”></div>
</div>
css:
.flex-container{max-width: 960px; margin: 0 auto; display:flex;}
.box{height: 100px; min-width: 100px;}
.one{background: pink;}
.two{background: lightgreen;}
.three{background: skyblue;}
效果:

效果与浮动布局类似,但是如果用浮动实现的话需要写更多的代码,而 flex 一行就搞定了。
1. Justify Content
如果我们想让 flex item 居中排列呢,我们可以给 flex container 增加一个 css 属性:justify-content,它控制 flex item 在主轴方向(main axis,由 flex-drection 决定,默认为水平方向)上的对齐方式:
.flex-container{

justify-content: center;
}
效果如图:

除此之外 justify-content 还可以设置为 flex-start, flex-end, space-around, space-between, space-even 等值,具体效果请自行实验。
2. Align Items
实现了 flex 方向的居中后,垂直于主轴方向(cross axis)的居中可以用 align-items 实现。
css:
.flex-container{
max-width: 960px;
margin: 0 auto;
display:flex;
justify-content: center;
height: 200px;
background-color: white;
align-items: center;
}
效果:

使用 flex 解决了以往 css 垂直居中实现复杂的问题!相应的,align-items 还有 flex-start, flex-end 等其他值。
3. Flex Direction
flex-direction 决定了主轴方向即 flex item 排列方向,除了默认的 row 方向之外,还可以纵向、反向(row-reverse/column-reverse)排列 flex item:
css:
.flex-container{

flex-direction: column;
align-items: center;
}
效果:

4. Flex Wrap
如果我们不想在窗口变窄的情况下压缩 flex item,而是让超出边界的 flex item 换行显示那我们可以设置 flex container 的 flex-wrap:
.flex-container{
max-width: 960px;
margin: 0 auto;
display:flex;
flex-wrap: wrap;
}

.box{
height: 100px;
min-width: 300px;
flex-grow: 1;
}
当我们压缩窗口的时候,效果如下:
flex wrap 还有一个值:wrap-reverse,设置该值后,被 wrap 的元素会排到其他元素上面:

由此可见,flex wrap 一定程度上可以取代 media query 了。
5. Flex Row
最后,flex-direction 和 flex-wrap 可以合并为一个属性 flex-flow,比如:flex-flow: row-reverse wrap。
Flex Item
1. Flex Grow
在上面所有的例子中,三个 flex item 只占据了 flex container 小部分空间,如果想让 flex item 占满 flex container 我们需要给 flex item 设置 flex-grow 属性。顾名思义,grow 意味着增长,用于控制 flex item 的尺寸的伸展。
将 css 修改为:
.box {
height: 100px;
min-width: 100px;
flex-grow:1;
}
效果:

可以看到三个子元素平分了父元素的空间,因为此时它们的 flex-grow 都是 1。如果只有一个子元素设置了 flex-grow 呢?
css:
.box{height: 100px; min-width: 100px;}
.one{background: pink; flex-grow: 1;}
效果:

此时 two 和 three 的大小不变,而 one 占据了父元素剩余空间。
如果将 one 的 flex-grow 改为 2,而 two 和 three 改为 1,我们看看会发生什么:
css:
.box{height: 100px; min-width: 100px; flex-grow:1;}
.one{background: pink; flex-grow: 2;}
效果:

可以看到 one 的宽度变成了 two 和 three 的两倍,因此 flex item 的尺寸和 flex-grow 的值成正比。
2. Flex Shrink
与 flex-grow 相对的是 flex-shrink,flex-shrink 用于控制子元素尺寸超过 flex container 后,对子元素的压缩。请看示例:
修改 box 的宽度为 flex container 的 1 /3,one、two、three 的 flex-shrink 分别为 1,2,3:
.box{height: 100px; width: 320px;}
.one{background: pink; flex-shrink: 1;}
.two{background: lightgreen; flex-shrink: 2;}
.three{background: skyblue; flex-shrink: 3;}
当窗口正常尺寸时,效果如下:

当我们压缩窗口使其变得更窄后,效果如下:

当 flex container 宽度变为 540px 后,子元素都被不同程度的压缩了。压缩后的 one、two、three 的宽度分别为 250px、180px、110px,所以相比于初始宽度 320px 被压缩掉的宽度分别为 70px、140px、210px,70 : 140 : 210 = 1 : 2 : 3,与 flex shrink 的值成反比。实际上压缩率和 flex item 的初始尺寸也有关系,只不过当初始尺寸一样时它带来的影响被忽略了。
假设 flex shrink 为 fs,flex item 的初始尺寸为 is,flex item 被压缩的尺寸为 ss,则正确的表达式为:
fs ∝ is/ss
3. Flex Basis
flex-basis 用于设置 flex item 的初始宽 / 高。为什么有 width 和 height 还需要重新加一个 flex-basis 呢?flex-basis 和 width/height 有如下的区别:

flex-basis 只能用于 flex-item,而 width/height 可以应用于其他类型的元素;
flex-basis 和 flex-direction 有关,当 flex-direction 为 row 的时,flex-basis 设置的是宽度,当 flex-direction 为 column 时,flex-basis 设置的是高度;
当 flex item 被绝对定位后(absolute position),flex-basis 不起作用,而 width/height 可以;
flex-basis 可以用于 flex 的简写形式,如:flex: 1 0 200px;

我们来看一下 flex-basis 的作用,将 css 修改如下:
.box{
height: 100px;
flex-grow: 1;
}
.one{
background: pink;
flex-basis: 100px;
}
.two{
background: lightgreen;
flex-basis: 200px;
}
.three{
background: skyblue;
flex-basis: 300px;
}
3 个 flex item 都在原来的初始宽度基础上增加了相同的宽度:

当然,这个例子如果换成使用 width 也是一样的效果,但是虽然效果一样但意义不一样,所以使用 flex 布局时还是应该尽量遵守规范,选合适的人去干正确的事。
4. Order
通过 order 属性我们可以改变 flex item 的排列顺序,例如:
html:
<section id=”blocks”>
<div class=”one”>1</div>
<div class=”two”>2</div>
<div class=”three”>3</div>
<div class=”four”>4</div>
</section>
css:
#blocks{
display: flex;
margin: 10px;
justify-content: space-between;
}

#blocks div{
flex: 0 0 100px;
padding: 40px 0;
text-align: center;
background: #ccc;
}
默认排列顺序是按照 flex item 在 html 中的出现顺序:

当我们修改 flex item 的 order 值后,flex item 会按照 order 值升序排列:
css:
.one{order: 4;}
.two{order: 3;}
.three{order: 2;}
.four{order: 1;}
效果:

结语
flex 就先简单介绍到这里,flex 很强大也很简单,希望大家用的开心。

退出移动版