引文
首先,我们有表格布局。当不考虑语义并且利用一些适当的嵌套和其他技巧,我们可以用table建立具有一定功能的布局。
然后是现在大多数人都在使用的浮动布局。我们可以使用任何我们想用的元素,但浮动并不适用于初学者。表面上它看起来很基础,但背后复杂的功能可以使经验丰富的开发者看着自己的屏幕不知所措。另外,浮动布局有一个缺点就是需要通过额外的元素清除浮动,或者更好一点,可以清除CSS浮动而不添加额外的标签。
这些缺点使得浮动布局不是很容易掌握,因为没有一个默认的方法可以建立起浮动与元素之间的关系,所以我们还需要更多的方法来实现多栏等高布局。
然后有些人开始使用display: table,display: table-cell等,但由于直到IE8 Internet Explorer浏览器才支持,人们似乎放弃了而只是接受float作为实际解决方案。
鉴于以上方案的缺点,弹性布局(Flex)的优势不言而喻:
- 独立的高度控制与对齐。
- 独立的元素顺序。
- 指定元素之间的关系。
- 灵活的尺寸和对齐方式。
开始使用弹性布局
弹性布局的实现需要一些看上去“很新的”CSS属性定义。下面罗列了这些属性,很多文章中都对这些内容有些详尽的解释,这里不再冗述。
概念
你在使用伸缩布局的时候你应该熟悉的一个概念是主轴与侧轴,与常说的 X、Y 轴有点像,不过也有点差异。主轴是伸缩布局流向的那个方向的轴,也就是在横排的时候是水平轴,在竖排的时候是垂直轴:
属性
display:flex | inline-flex;
定义弹性盒容器
flex-direction:row | row-reverse | column | column-reverse
定义主轴方向
flex-wrap:nowrap | wrap | wrap-reverse
定义侧轴方向单行或多行
flex-flow
‘flex-direction’ 和 ‘flex-wrap’的组合简写
justify-content:flex-start | flex-end | center | space-between | space-around
定义主轴上子元素的排列方式
align-items:flex-start | flex-end | center | baseline | stretch
定义侧轴上子元素高度的伸缩
align-content:flex-start | flex-end | center | space-between | space-around | stretch
定义侧轴上子元素的排列方式
order
子元素的显示顺序
flex-grow
父元素拉伸时子元素的拉伸比例值
flex-shrink
父元素缩小时子元素的收缩比例值
flex-basis
子元素的初始显示比例值
flex
flex-grow [,flex-shrink,flex-basis]的简写形式
align-self:auto | flex-start | flex-end | center | baseline | stretch
提供给单个子元素覆盖父元素align-items值的能力
以上的CSS成为“新”的弹性盒模式,事实上,只有最近的几个Chrome内核(包括桌面版Chrome+、Android版Chrome、Opera 15+)支持这种写法,Firefox的支持还不够完善(详细信息点击这里)。更多的现代浏览器从几年前开始支持一种“老的”弹性盒模型语法,除了IE10。IE10似乎支持一种介于老语法与新语法之间的新语法。下面的表格显示了它们之间的关系:
含义 | 新语法(-webkit-,-moz-) | 老语法(-webkit-,-moz-) | IE10语法 | |
---|---|---|---|---|
1 | 弹性容器定义 | display : flex | display : box | display : -ms-flexbox |
2 | 子元素排列方式 | flex-direction : row | column-row | reverse | column-reverse | box-orient: horizontal | vertical | inline-axis | block-axis | inherit | -ms-flex-direction : row | column | row-reverse | column-reverse | inherit |
3 | 主轴子元素分布 | justify-content : flex-start | flex-end | center | space- around | space-between | box-pack : start | end | center |justify( firefox ) | -ms-flex-pack : start | end | center | justify |
4 | 侧轴子元素分布 | align-content : flex-start | flex-end | center | space- around | space-between |
NOT SUPPORTED | -ms-flex-line-pack: start | end | center | justify | distribute | stretch |
5 | 侧轴方向子元素对齐 | align-items : flex-start | flex-end | center | stretch | box-align : start | end | center | baseline | stretch | -ms-flex-align: start | end | center | baseline | stretch |
6 | 弹性子元素伸缩值 | flex : [positive-flex] [negative-flex] [preferred-size] |
box-flex: [positive-flex] | -ms-flex : [positive-flex] [negative-flex] [preferred-size] |
7 | 子元素排列顺序 | order : 1 | box-ordinal-group : 1 (positive) |
-ms-flex-order : 1 |
8 | 在子元素中覆盖父元素定义的第5项 | align-self : flex-start | flex- end | center | stretch |
NOT SUPPORTED | -ms-flex-item-align: auto | start | end | center | baseline | stretch |
9 | 换行 | flex-wrap : wrap | no-wrap | wrap-reverse | NOT SUPPORTED | -ms-flex-wrap : none | wrap | wrap-reverse |
看上去应用这个新的模型还太过乐观,至少在桌面环境中。
尽管很多人不推荐继续使用老旧的语法,但是现实是这个语法已经被iOS和Android上webkit支持的足够完善,并且看上去会在相当长一段时间里继续支持下去。因此如果你不是新事物的狂热支持者,并且仅需考虑iOS和Android这两大移动平台的webkit浏览器,可以考虑使用新老语法混合的方式开发你的网站。
如何区分新旧版本的语法请点击“Old” Flexbox and “New” Flexbox。
新版本的支持情况:
IE | Firefox | Chrome | Safari | Opera | iOS Safari | Opera Mini | Android Browser | Blackberry Browser | |
---|---|---|---|---|---|---|---|---|---|
2.1-webkit- | |||||||||
2.2-webkit- | |||||||||
3.2-webkit- | 2.3-webkit- | ||||||||
4.0-4.1-webkit- | 3.0-webkit- | ||||||||
8.0 | 4.2-4.3-webkit- | 4.0-webkit- | |||||||
9.0 | 21.0-moz- | 27.0-webkit- | 5.1-webkit- | 5.0-5.1-webkit- | 4.1-webkit- | 7.0-webkit- | |||
Current | 10.0-ms- | 22.0 | 28.0-webkit- | 6.0-webkit- | 15.0-webkit- | 6.0-6.1-webkit- | 5.0-7.0 | 4.2-webkit- | 10.0-webkit- |
Near future | 11.0 | 23.0 | 29.0 | 7.0-webkit- | 16.0-webkit- | 7.0-webkit- | |||
Farther future | 24.0 |
由于老版语法对多行支持不好,因此你最好在一个flex容器内仅包含一行子元素。这导致flex在响应式设计中的应用变得低能:元素不能在父元素的宽度缩小时进行折行处理。在纯粹的响应式站点设计中,自动折行仍然难以用flex实现。
在iOS和Android浏览器中,老版语法的flex仍然具有其巨大的应用价值。由于移动版站点一般要铺满整个宽度,而设备的屏幕的像素宽度是多种多样的,因此现在的移动站点中大量采用百分比的方式分配子元素的宽度,以期望能适应不同的屏幕宽度。
比如,一个区块包含排在一行的两个元素:一张图和一大段文字,分别占宽40%和60%。文字可能很长,难以显示完整。在设备横屏时,文字可以显示的更多,就像这个样子:
图图图图 文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文
图图图图
图图图图
但是图片的固定宽度的,在横屏时它不需要占用40%这么大的位置,我们期待会这样排列:
图图图图 文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文
图图图图
图图图图
如果不使用浮动的话,那么flex布局将是一个不错的选择。元素可以灵活分配固定宽度元素之外的剩余空间。本里中就是最大化地为文字提供了尽量多的显示空间。类似的,一个占满一行而又需要左边补白20px的元素,无需设置宽度为calc(100% - 20px),当然,calc支持度也不够广泛。
此外水平居中定位更简单了。在这以前垂直居中稍显棘手,要么使用负外边距,要么使用display:table-cell。现在可以使用:
-webkit-box-align: center;//老语法
-webkit-align-items: center;//新语法
就可以达到。
总结
虽然老版本的flex语法难以匹敌新版语法,但是仍然有很多支持广泛并且有用的特性。
像下面这样写CSS,可以方便的应用flex带来的排版上的方便。
.f-f{display: -webkit-box;display: -webkit-flex;}
.f-vc{-webkit-box-align:center;-webkit-align-items:center;}/*垂直居中*/
.f-hc{-webkit-box-pack:center;-webkit-justify-content:center;}/*水平居中*/
.f-hr{-webkit-box-pack:end;-webkit-justify-content:flex-end;}/*向右靠拢*/
.f-hl{-webkit-box-pack:start;-webkit-justify-content:flex-start;}/*向左靠拢*/
当然flex的功能远远不止这些,使用新版flex语法将带来更大的灵活性。
有人将各种flex语法写成Sass:
@mixin flexbox() {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
@mixin flex($values) {
-webkit-box-flex: $values;
-moz-box-flex: $values;
-webkit-flex: $values;
-ms-flex: $values;
flex: $values;
}
@mixin order($val) {
-webkit-box-ordinal-group: $val;
-moz-box-ordinal-group: $val;
-ms-flex-order: $val;
-webkit-order: $val;
order: $val;
}
如果你的页面只需要应付webkit浏览器,那么完全不用考虑兼容性。除此之外,你还可以考虑应用新版本的语法,虽然支持的移动浏览器还不错,不过,向后优化总是好的。