CSS3 中的弹性盒布局(Flexible Box Layout)标准已经进入候选推荐阶段,大部分浏览器也开始支持这个标准了,这里我们来介绍下这个标准。
在最新的 Chrome 中浏览下面的例子,可以看到父元素被横向分为三部分,而当鼠标移动到某一部分上面时,各部分的宽度会自动调整:
<!DOCTYPE html> <html><head> <style> .flex { 420px; height: 250px; border: 1px solid #555; display: -webkit-flex; -webkit-flex-direction: row; } .flex > div:nth-child(1) { -webkit-flex: 1 1 auto; background : #009246; } .flex > div:nth-child(2) { -webkit-flex: 2 1 auto; background : #F1F2F1; } .flex > div:nth-child(3) { -webkit-flex: 3 1 auto; background : #CE2B37; } .flex > div { -webkit-transition: width 0.7s ease-out; 60px; } .flex > div:hover { 240px; } </style> </head><body> <div class="flex"> <div>one</div> <div>two</div> <div>three</div> </div> </body></html>
在上面的例子中首先我们设置了父元素的 display: flex; flex-direction: row; ,表示我们使用横向的弹性布局。display 也可以设为 inline-flex,这时候父元素就类似于 inline-block 的元素。
接下来我们对三个子元素分析设置了 flex 属性。flex 属性由三个值组成:flex-grow,flex-shrink 和 flex-basis。flex-grow 表示空间剩余时自动增加的份额,flex-shrink 表示空间不足时自动收缩的份额。而 flex-basis 表示初始大小。在调整空隙时,先计算父元素的大小以及各元素初始大小之和,得到两者的差,然后根据各个子元素的份额增加或者减少它们的大小。
flex-grow 和 flex-shrink 的默认值是 1;而 flex-basis 的初始值是 0;如果 flex-basic 设置为 auto,它的值就从该元素的 width 或 height 中取得。
根据上面的方法,在刚开始时,由于剩余的宽度为 420 - 60×3 = 240,而三个子元素的分配份额为 1:2:3,所以各分得 40,80 和 120。从而三者的实际宽度分别为 100px,140px 和 180px。类似地,我们可以计算出悬停状态下各部分的宽度变化,如下表:
总共宽度 | 剩余宽度 | 左栏宽度 | 中栏宽度 | 右栏宽度 | |
初始状态 | 420 | 240 | 60 + 40 = 100 | 60 + 80 = 140 | 60 + 120 = 180 |
左栏悬停 | 420 | 60 | 240 + 10 = 250 | 60 + 20 = 80 | 60 + 30 = 90 |
中栏悬停 | 420 | 60 | 60 + 10 = 70 | 240 + 20 = 260 | 60 + 30 = 90 |
右栏悬停 | 420 | 60 | 60 + 10 = 70 | 60 + 20 = 80 | 240 + 30 = 270 |
由于这个标准经过较大的改动,虽然主流浏览器都支持它,但是也许并不兼容。目前为止,支持最新标准的浏览器只有 Chrome 21+ 和 Firefox 22+,其中 Firefox 中无需特殊前缀。详情可见下面的参考资料。
参考资料:
[1] W3C - CSS Flexible Box Layout Module
[2] Using CSS flexible boxes - MDN
[3] Flexbox playground and code generator
[4] Can I use Flexible Box Layout Module?
[5] 跨浏览器弹性布局进阶教程 | 欧朋开发者社区
[6] 弹性方框模型 (Flexible Box Model) 快速入门
[7] CSS box-flex属性,然后弹性盒子模型简介
[8] CSS3 弹性盒模型与流式布局 - leecan_zeng - 博客园
[9] “Old” Flexbox and “New” Flexbox | CSS-Tricks