相信研究过CSS3的同窗对Flexbox布局必定不会陌生(做为一个将来主流的布局方式,至少有所耳闻)。最近完成了两个项目:一个是移动端H5项目,一个是嵌入HTML页面的mac客户端项目。为了庆祝这两个项目不用再兼容万恶的IE,同时要体现出现代浏览器的优点,决定在项目中尝试使用Flexbox布局。项目第一个版本完成后回过头来看,仍是有很多须要注意的地方。现将项目中的一些经验总结一下,但愿可以对想尝试使用Flexbox的同窗有所帮助,在恰当的地方使用恰当的布局方法。css
Flexbox布局俗称伸缩布局,它能够简单快速的建立一个具备弹性功能的布局。一个Flexbox布局是由一个伸缩容器(flex containers)和在这个容器里的伸缩项目(flex items)组成。伸缩容器(flex containers)是一个HTML标签元素,而且“display”属性显式的设置了“flex”属性值。在伸缩容器中的全部子元素都会自动变成伸缩项目(flex items)。当在一个小屏幕上显示的时候,Flexbox可让元素在容器(伸缩容器)中进行自由扩展和收缩,从而容易调整整个布局。html
Flexbox布局可以让咱们很轻松的实现如下效果:前端
这些效果是否是很诱人,为了咱们都能更好的理解接下来的内容,须要对Flexbox有一个初步的认识。没有了解过Flexbox知识的同窗请先移步伸缩布局--打开布局天堂之门!android
若是已经对Flex有了初步了解,那让咱们来举例说明何时更适合使用该布局。ios
【No.1】youku H5播放页的控制区域css3
将浏览器的UA改成ios或者android,而后访问youku的播放页。先来看下示意图:web
播放区域分为四个部分:mod-one为播放按钮区域,mod-two为时间显示区域,mod-three为切换视频质量和其余操做区域,mod-four为全屏按钮区域。浏览器
该播放区域的排版需求以下:mod-one和mod-two定宽依次居左,mod-four定宽居右,mod-three自动填充剩余的宽度且该区域内的元素依次居右排列(除了切换视频质量按钮外还有其余操做按钮)。ide
下面来看看youku如何使用Flexbox进行html布局以及css实现:布局
x-controls为Flexbox伸缩容器,核心样式以下:
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;
box-orient: horizontal;
该css设置了x-controls为Flexbox容器,子元素(伸缩项目)横向排列。box-pack没有设置,默认为start,即弹性盒模型对象的子元素从开始位置对齐。
PS:使用Flexbox布局的时候尽可能使用兼容语法,避免使用最新语法致使旧版系统(android2.2,ios5)出现不兼容的状况。
若是要兼容Windows Phone(IE10+)须要加入IE专有语法(IE和其余浏览器语法稍有区别,必定要注意),详见最后附上的兼容代码。
回到youku播放页,x-play-control为播放按钮区域,根据需求只须要设置宽度便可。x-time-display为时间显示区域,css设置同播放按钮区域。
x-settings须要设置自动填充屏幕剩余宽度,同时该模块内的子元素须要居右显示,所以它既要做为一个伸缩项目,又要做为一个伸缩容器。css代码以下:
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;
box-orient: horizontal;
-webkit-box-pack: end;
-moz-box-pack: end;
box-pack: end;
-webkit-box-flex: 1;
-moz-box-flex: 1;
box-flex: 1;
为告终构的合理性,youku将x-fullscreen放到了x-settings中,所以须要绝对定位到最右侧。不然能够将x-fullscreen做为兄弟节点放到x-settings后,一样也能实现该效果。
【NO.2】UC网址导航
某天使用UC浏览器的网址导航,下意识的查看了一下源码,发现其导航部分也使用了Flexbox布局。内心暗喜,这也算是为推动CSS3在国内的普及作出了一点贡献。
直接用浏览器访问该网址,示意图以下:
该需求比较简单,8个标签两两一组。4组平均分配屏幕宽度。
html结构及样式以下:
block为伸缩容器,设置以下样式:
display: -webkit-box;
-webkit-box-pack: justify;
block-list为伸缩项目,设置以下样式:
-webkit-box-flex: 1;
width: 25%;
简单的几句css就实现了自动伸缩的布局。固然,这个例子比较简单,使用css2的技术也能够实现,好比block-list中的width: 25%; 我想就是起了优雅降级的做用。
先让咱们看一个需求:
一样是一个播放器的操做区域,分为三部分:左边为视频质量选择按钮,居左显示;中间为控制视频进度的按钮组,居中显示;右边为分享和全屏按钮,居右显示。
了解需求后我很兴奋,刚刚学习的Flexbox布局终于有用武之地了。无论三七二十一便为这版UI制定了两套方案:
两套方案html结构相同,如图:
CSS方案略有不一样,方案一:
不给伸缩项目定宽,直接使用box-pack:justify将3个伸缩项目定位到图中的位置,代码:
display: -webkit-box;
display: -ms-flexbox;
display: box;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
box-pack: justify;
-webkit-box-orient: horizontal;
-ms-box-orient: horizontal;
box-orient: horizontal;
不用给伸缩项目写任何css便可实现UI中的效果,完成后感慨Flexbox简直是逆天的存在!
方案二:
给三个伸缩项目div设置-webkit-box-flex:1; 而后分别给第一个设置text-align: left; 第二个设置text-align: center; 第三个设置text-align: right; 能够经过css3的:first-child和:last-child完成。
某天,前端开发的过程当中,产品跑来对我说:分享按钮这期先不上。so easy,我直接使用display: none隐藏了分享对应的 a 标签。
而后……相信已经有同窗发现会出现神马情况了。
我去,中间的按钮往右移动了。不论使用方案一仍是方案二都会出现此问题。经过分析后发现,在方案一中,因为我伸缩项目的宽度都是根据其内容撑开的。因此右侧子内容不见了,伸缩项目的宽度天然也就发生了变化,从新分配三个伸缩项目后就是图中的效果。而方案二虽然设置了伸缩比flex:1; 可是整体宽度仍是和容器的内容有关系。后来仔细想一想,虽然此次歪打正着提早遇到了问题,但就算分享功能定期上线,并非全部视频都提供分享,所以最终仍是会出现这个问题。
如何解决呢?
对于这种包含居中显示的布局(且需求可能随时会变化),最好的方法是左右两个伸缩项目定宽。中间的伸缩项目设置flex:1,具备固定宽度的伸缩项目不会对弹性的伸缩项目产生影响。这个例子告诉咱们,在了解需求的基础上,尽可能将布局作的通用性强一点,可以适应更多的突发状况。CSS近几年一直推崇的OOCSS理念即如此。
最后说一个Flexbox实现的水平、垂直居中例子:
伸缩容器设置以下样式,伸缩项目不管是否认义宽高均可实现水平、垂直居中效果。
html代码:<div class="flexbox"><div>这里能够听任何元素</div></div>
/* 旧版语法 */ display: -webkit-box; display: -ms-flexbox; -webkit-box-pack: center; -ms-flex-pack: center; -webkit-box-align: center; -ms-flex-align: center; /* 新版语法 */ display: -webkit-flex; display: flex; -webkit-align-item: center; align-item: center; -webkit-justify-content: center; justify-content: center;
附上一段Flexbox新老版本兼容及对应语法的代码,供你们参考。
/* display */ display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */ display: -moz-box; /* OLD - Firefox 19- (doesn't work very well) */ display: -ms-flexbox; /* TWEENER - IE 10+ */ display: -webkit-flex; /* NEW - Chrome */ display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */ /* 沿着主轴方向对齐项目 */ -webkit-box-pack: start; -moz-box-pack: start; -webkit-justify-content: flex-start; -ms-flex-pack: start; justify-content: flex-start; /* 沿着侧轴方向对齐项目 */ -webkit-box-align: start; -moz-box-align: start; -webkit-align-item: flex-start; -ms-flex-align: start; align-item: flex-start; /* 伸缩项排列方式 */ -webkit-box-direction: normal; /* 旧版伸缩项对齐方式,在新版中已经合并到了flex-direction */ -moz-box-direction: normal; -webkit-box-orient: horizontal; -moz-box-orient: horizontal; /* vertical */ -webkit-flex-direction: row; /* column, row-reverse, column-reverse */ -ms-flex-direction: row; flex-direction: row; /* 伸缩项目是否换行 */ -webkit-flex-wrap: nowrap; -ms-flex-wrap: nowrap; flex-wrap: nowrap; /* 多行伸缩容器的对齐 */ -webkit-align-content: stretch; -ms-flex-line-pack: stretch; align-content: stretch; /* 改变伸缩项布局顺序和使伸缩项目可适应伸缩容器 */ -webkit-box-ordinal-group: 1; -moz-box-ordinal-group: 1; -ms-flex-order: 1; -webkit-order: 1; order: 1; -webkit-box-flex: 1; -moz-box-flex: 1; -webkit-flex: 1; -ms-flex: 1; flex: 1;
本篇文章目的是起到抛砖引玉的做用,帮助你们可以更快的将Flexbox布局运用到本身的项目中。我相信CSS将来发展的方向就是采用Flexbox这种布局方式。
因为本人也是刚开始接触Flexbox这种布局方式,有不少地方还须要继续研究。文中有任何不妥,或有任何建议欢迎你们提出!