导语:
布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。2009年,W3C提出了一种新的方案----Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了众多主流浏览器的支持,这意味着,flex有了更多的用武之地。
Flex布局是什么?
Flex是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
任何一个容器都可以指定为Flex布局。
.box{
display: flex;
}
行内元素也可以使用Flex布局。
.box{
display: inline-flex;
}
Webkit内核的浏览器,必须加上-webkit前缀。
.box{
display: -webkit-flex; /* Safari */
display: flex;
}
注意,设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。
弹性布局(Flex)的优势:
独立的高度控制与对齐。
独立的元素顺序。
指定元素之间的关系。
灵活的尺寸和对齐方式。
归结:flex布局可以轻易做到垂直居中、重新排序、布局的动态伸展与收缩
布局(Flex)原理解析:
采用Flex布局的元素,称为Flex容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称"项目"。
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
布局(Flex)的属性:
flex有以下6个属性:
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content
布局(Flex)的兼容解决方案:
虽然flex布局早在2009年就有了,而现在是2015年8月10日,使用最新的flex语法会发现支持程度并不好,即使是在“高端”浏览器上也是如此,比如Chrome、Firefox、Safari、Android、IOS Safari下支持程度各不相同
网上现有的代码中充斥着各种版本,在Chrome下运行一般都没有问题,Firefox一般也还好,但Android与IOS Safari下就显得非常无力了。之所以会出现这样的局面,主要是历史原因,从2009年到2015年,期间W3C规范有了多次更新,浏览器支持程度也就有了差异。
Flexbox布局的语法经过几年发生了很大的变化,也给Flexbox的使用带来一定的局限性,因为语法版本众多,浏览器支持不一致,致使Flexbox布局使用不多。
Flexbox布局主要有三种语法版本:
2009版本,我们称之为老版本,使用的是“display:box”或者“display:inline-box”;
2011版本,我们称之为混合版本,使用的是“display:flexbox”或者“display:inline-flexbox”;
2013版本,也就是最新语法版本,使用的是“display:flex”或者“display:inline-flex”。
我们需要把Flexbox旧的语法、中间过渡语法和最新的语法混在一起使用,在这里他们的顺序显得非常重要。“display”属性本身并不添加任何浏览器前缀,我们需要确保我们老语法不要覆盖新语法让浏览器(可能总是会)同时支持。
伸缩容器:
.box {
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
设置排列顺序:
.main-content {
-webkit-box-ordinal-group: 2; /* OLD - iOS 6-, Safari 3.1-6 */
-moz-box-ordinal-group: 2; /* OLD - Firefox 19- */
-ms-flex-order: 2; /* TWEENER - IE 10 */
-webkit-order: 2; /* NEW - Chrome */
order: 2; /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
.main-nav {
-webkit-box-ordinal-group: 1;
-moz-box-ordinal-group: 1;
-ms-flex-order: 1;
-webkit-order: 1;
order: 1;
}
.main-sidebar {
-webkit-box-ordinal-group: 3;
-moz-box-ordinal-group: 3;
-ms-flex-order: 3;
-webkit-order: 3;
order: 3;
}
关于flex的W3C规范: http://dev.w3.org/csswg/css-flexbox-1/
浏览器兼容性可以参考CanIUse: http://caniuse.com/#feat=flexbox
根据CanIUse的数据可以总结如下:
- IE10部分支持2012,需要-ms-前缀
- Android4.1/4.2-4.3部分支持2009 ,需要-webkit-前缀
- Safari7/7.1/8部分支持2012, 需要-webkit-前缀
- IOS Safari7.0-7.1/8.1-8.3部分支持2012,需要-webkit-前缀
所以需要考虑新版本2012: http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/
而Android需要考虑旧版本2009: http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/
flex兼容常用的布局代码:
/* 子元素-平均分栏 */
.flex1 {
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */
-moz-box-flex: 1; /* OLD - Firefox 19- */
width: 20%; /* For old syntax, otherwise collapses. */
-webkit-flex: 1; /* Chrome */
-ms-flex: 1; /* IE 10 */
flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
/* 父元素-横向排列(主轴) */
.flex-h {
display: box; /* OLD - Android 4.4- */
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
/* 09版 */
-webkit-box-orient: horizontal;
/* 12版 */
-webkit-flex-direction: row;
-moz-flex-direction: row;
-ms-flex-direction: row;
-o-flex-direction: row;
flex-direction: row;
}
/* 父元素-横向换行 */
.flex-hw {
/* 09版 */
/*-webkit-box-lines: multiple;*/
/* 12版 */
-webkit-flex-wrap: wrap;
-moz-flex-wrap: wrap;
-ms-flex-wrap: wrap;
-o-flex-wrap: wrap;
flex-wrap: wrap;
}
/* 父元素-水平居中(主轴是横向才生效) */
.flex-hc {
/* 09版 */
-webkit-box-pack: center;
/* 12版 */
-webkit-justify-content: center;
-moz-justify-content: center;
-ms-justify-content: center;
-o-justify-content: center;
justify-content: center;
/* 其它取值如下:
align-items 主轴原点方向对齐
flex-end 主轴延伸方向对齐
space-between 等间距排列,首尾不留白
space-around 等间距排列,首尾留白
*/
}
/* 父元素-纵向排列(主轴) */
.flex-v {
display: box; /* OLD - Android 4.4- */
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
/* 09版 */
-webkit-box-orient: vertical;
/* 12版 */
-webkit-flex-direction: column;
-moz-flex-direction: column;
-ms-flex-direction: column;
-o-flex-direction: column;
flex-direction: column;
}
/* 父元素-纵向换行 */
.flex-vw {
/* 09版 */
/*-webkit-box-lines: multiple;*/
/* 12版 */
-webkit-flex-wrap: wrap;
-moz-flex-wrap: wrap;
-ms-flex-wrap: wrap;
-o-flex-wrap: wrap;
flex-wrap: wrap;
}
/* 父元素-竖直居中(主轴是横向才生效) */
.flex-vc {
/* 09版 */
-webkit-box-align: center;
/* 12版 */
-webkit-align-items: center;
-moz-align-items: center;
-ms-align-items: center;
-o-align-items: center;
align-items: center;
}
/* 子元素-显示在从左向右(从上向下)第1个位置,用于改变源文档顺序显示 */
.flex-1 {
-webkit-box-ordinal-group: 1; /* OLD - iOS 6-, Safari 3.1-6 */
-moz-box-ordinal-group: 1; /* OLD - Firefox 19- */
-ms-flex-order: 1; /* TWEENER - IE 10 */
-webkit-order: 1; /* NEW - Chrome */
order: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
/* 子元素-显示在从左向右(从上向下)第2个位置,用于改变源文档顺序显示 */
.flex-2 {
-webkit-box-ordinal-group: 2; /* OLD - iOS 6-, Safari 3.1-6 */
-moz-box-ordinal-group: 2; /* OLD - Firefox 19- */
-ms-flex-order: 2; /* TWEENER - IE 10 */
-webkit-order: 2; /* NEW - Chrome */
order: 2; /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
为了更好的兼容性,我们需要给容器声明flex-h/flex-v,而不是一般的flex:
/* 父元素-flex容器 */
.flex {
display: box; /* OLD - Android 4.4- */
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
建议在需要兼容Android时(2009版语法)采用flex-h/flex-v声明容器使用flex模式,在不需要兼容Android时(2012版语法)使用flex设置容器
注意:上面给的代码并不是完全兼容各个高端浏览器的,但要比任何其它现有代码兼容性好
开始使用弹性布局:
属性
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值的能力
虽然老版本的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;}/*向左靠拢*/
居中对齐示例:
<iframe src="http://codepen.io/webzsky/embed/YXgaZg/?height=254&theme-id=17151&default-tab=result" height="254" width="320" allowfullscreen="true" frameborder="no" scrolling="no" style="margin: 0px; padding: 0px; width: 760px;"></iframe>
水平垂直居中对齐示例:
<iframe src="http://codepen.io/webzsky/embed/rVRdwp/?height=268&theme-id=17151&default-tab=result" height="268" width="320" allowfullscreen="true" frameborder="no" scrolling="no" style="margin: 0px; padding: 0px; width: 760px;"></iframe>
css3 flex流动自适应响应式布局样式类
flex布局非常适宜当前的移动设备和大屏幕浏览器网页开发非常的便捷,是未来网页开发布局设计的方向,是一个未来技术。flex布局能够编写代码小,各种宽度、高度、位置都由浏览器自身按照既定规则完成适配,跨平台无障碍阅读体验。
css3 flex特点
一旦一个容器赋予了display:flex属性,将会有以下特点:
项目无法设置浮动。
列表的样式会被清除。
无法使用vertical-align设置垂直对齐方式。
flex 样式类
- css3 flex 的部分属性在ie和火狐下表现不佳或支持不完善,其中ie9及以下完全不支持,ie10不支持
flex-grow
(即.flex-grow-0 .flex-grow-1
类),火狐24不支持flex-wrap
(即.flex-wrap
类)。 - css3 flex 布局以主轴在水平方向、侧轴在垂直方向为准,行(主轴)为水平方向、列(侧轴)为垂直方向。当主轴在垂直方向、侧轴在水平方向时,行即为垂直方向,列即为水平方向。无论怎样,行都为主轴、列都为侧轴。
- 以下各个flex布局类命名均以主轴在水平方向为准,即主轴为行;并且大部分类名都是应用在父级flex容器上的,除了
.flex-grow-0 .flex-grow-1
。 - flex容器:
- 行布局:
.flex-row
- 行反布局:
.flex-row-reverse
- 列布局:
.flex-col
- 列反布局:
.flex-col-reverse
- 换行布局(默认是不支持换行的*):
.flex-wrap
- 行布局:
- flex容器单行水平方向项目排列方式
- 开始方向排列:
.flex-row-start
- 居中方向排列:
.flex-row-center
- 结束方向排列:
.flex-row-end
- 两端方向排列,开始结束有余白:
.flex-row-around
- 两端方向排列,开始结束无余白:
.flex-row-between
- 开始方向排列:
- flex容器多行垂直方向项目排列方式
- 开始方向排列:
.flex-rows-start
- 居中方向排列:
.flex-rows-center
- 结束方向排列:
.flex-rows-end
- 两端方向排列,开始结束有余白:
.flex-rows-around
- 两端方向排列,开始结束无余白:
.flex-rows-between
- 开始方向排列:
- flex容器单行垂直方向项目对齐方式
- 开始对齐:
.flex-col-start
- 居中对齐:
.flex-col-center
- 结束对齐:
.flex-col-end
- 拉伸对齐:
.flex-col-stretch
- 开始对齐:
- flex项目垂直方向项目对齐方式(与
.flex-col
类似,只是其优先级更高)- 开始对齐:
.flex-self-start
- 居中对齐:
.flex-self-center
- 结束对齐:
.flex-self-end
- 拉伸对齐:
.flex-self-stretch
- 开始对齐:
- flex项目在剩余空白上分配占比
- 占比为0:
.flex-grow-0
- 占比为1:
.flex-grow-1
- 占比为0:
flex自适应布局在路上....
参考资料:
1. http://www.w3cplus.com/css3/using-flexbox.html