【译】现在实现flexbox 的策略和工具(flexbox兼容到IE8的跨浏览器解决方案)
flexbox 相当好用,但是现在就可以用flexbox并且让它支持到IE8吗?如果你跟着下面的步骤,现在就可以开始用flexbox啦。
_
我介绍flexbox已经有一段时间了,别人问得最多的问题是“什么时候flexbox能得到足够好的支持,可以用到实际的项目中?”
我总觉得flexbox在快速原型开发中有一席之地。但我也认为进行小小的规划,大多数人现在就可以将flexbox用在实际的产品中。
在这篇文章中,我们一起探索将flexbox用在产品中的条件、最佳的设计方案和兼容到IE8。
我们用的demo是我朋友正在开发的一个小项目的注册页。皮特在用BootStrap的栅格系统时遇到的一些布局问题,如果用flexbox就很容易解决,所以这是一个很好的例子。下面这个是我们将要创建的布局。
这个demo的代码可以在Github上找到。
我们可以会遇到以下四个场景:
只支持最先进的浏览器
你的网站IE用户很少
必须支持IE8,但是网页布局可以不一样
必须支持IE8,布局看起来要一致。
场景#1,你只需支持最先进的浏览器
我们以最理想的场景开始,但是我们很快就要解决IE8的问题。
我在看自己网站的流量监控时,IE用户几乎是没有的。只有大约1%的用户用的是IE10/11。这个博客和我的网页是给像你这样的开发者看的,所以我只需要支持像我们这些人用的最新浏览器就可以了。
如果你的网站是像我这样的,你现在就可以用flexbox最新的语法了,但是要注意这点:
不要用flex-wrap,因为这个属性不支持版本号低于28的firefox浏览器。
除了无前缀语法外,加上-webkit-前缀。
不要用在整体页面布局
遵循这些规则,你就可以放心用flexbox了。
让我们一起来用flexbox布局来写下这个例子。
最上面不同定价计划的盒子是一个可伸缩的容器,皮特想让按钮对齐在底部。如果外部容器是一个flex容器,并且align-items设为stretch(默认),那么所有的盒子会有相同的高度,按钮很自然地排在了底部,并且按钮自动分配间距。
首先,让整块区域变成一个可伸缩的容器。
.plans { display: -webkit-flex; display: flex; }
这会让它们排成一行,并且垂直拉伸。
然后将价格容器变成可伸缩的容器。将direction设为column,并且将align-items设为flex-start;否则这些按钮会拉伸,充满整个水平空间。
.plans > div { display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; -webkit-align-items: flex-start; align-items: flex-start; }
现在剩下的就是将按钮放到底部,选中按钮,并设置margin-top:auto;
.plans > div a { margin-top: auto; }
我会用这样的方式在页面的其他地方用flexbox,因为我假设你已经了解过flexbox,所以我不会说太多的细节。(如果还不了解flexbox,请看这里)
场景#2:你的网站IE用户很少
即使低版本的浏览器有一点点流量,你也想让IE10和firefox25或者更低版本的浏览器也能正常浏览。
如果在最新的语法中加上旧版本的flexbox的写法,你可以让IE10和低版本的firefox、safari和opera也能正常浏览。(去 Can I Use 查看更多浏览器支持的信息)
将flexbox加上所有的前缀是一件很繁琐的事情,所以用Autoprefixer来替你自动完成吧。如果你没有用过Grunt/Gulp/makefiles或者类似的工具,这里可以让你学习使用Grunt和Autoprefixer。
在这种方法中,不要使用自动间距,因为它们不会支持所有的版本。同时要对IE10进行全面的测试,因为IE10中会有一些Bug。例如,我需要将按钮上面的段落宽度设为100%,否则,文字会超出容器之外(没有自动间距之后,我必须伸缩段落和将按钮挤到底部。)。
下面是定价包区域的代码,让你感受一下autoprefixer。
.plans { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; } .plans > div { -webkit-box-flex: 1; -webkit-flex: 1 1 33%; -ms-flex: 1 1 33%; flex: 1 1 33%; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; -webkit-box-align: start; -webkit-align-items: flex-start; -ms-flex-align: start; align-items: flex-start; } .plans > div .stretch { width: 100%; -webkit-box-flex: 1; -webkit-flex: 1 0 auto; -ms-flex: 1 0 auto; flex: 1 0 auto; }
使用Autoprefixer,你可以自动生成这些代码,所以你只需要写最新的语法即可。还有额外的好处是,你不单可以在写flexbox时用它,还可以将它用在所有的CSS上。
场景3:必须支持IE8,但是网页布局不需如此漂亮
大部分客户和老板都想网页在所有支持的浏览器中看起来都一样,但也有少数客户和老板希望渐进增强。
在这种情况下,渐进增强的方式下,IE8的用户看到的价格包不需要排成一行。你可以将flexbox和旧式布局样式联合起来使用。如果flexbox可用,将会应用flexbox样式,如果浏览器不支持,浏览器将会忽略flexbox布局,回退到简单的布局。
佐伊·吉伦瓦特(Zoe Gillenwater)几个月前对此作了很精彩的介绍,这是她文章的地址。
这是使用flexbox最保险的方法并且支持旧版本的浏览器,但是这也意味着代码的冗余,并且要找出能“很好地支持”的客户端,而且老板有时是不好说话的。
在我们这个例子中,最简单的方法是:在IE8和IE9中,我们不需要将按钮底部对齐,但是依旧需要将价格区块排成一行,所以我们使用float。
.plans > div { width: 33%; float: left; flex: 1 1 0; display: flex; flex-direction: column; align-items: flex-start; ·}
(注意:这里展示的是最新的语法,但是这些代码在演示地址中已经自动补全了)
flex-direction设为column,并且价格计划中的每个元素都是块元素。因为它们已经垂直排列,所以我们在这里不需要再做其他事情。
注册框是一个可伸缩容器,所以我们要设定宽度和display属性。
.well form .inputs #email { width: 50%; display: inline; flex: 1 0 auto; } .well form .inputs .btn { width: 250px; width: 25rem; margin-left: 16px; margin-left: 1rem; }
footer也是一个可伸缩容器,所以也添加一些float。你应该明白我的意思了。下面是在IE8下的效果。
场景#4:必须要支持IE8和IE9,并且看起来一模一样
如果你在这种范畴内,你可能会根本不想用flexbox。你不是完全无望,但是可用的选项是有限的。
你可以使用flexbox跨浏览器插件flexie.js,但是它只对其中一种旧的flexbox语法起作用,不支持新的语法。你可能会想,我可以用Autoprefixer,然后再为IE9和更旧版本的浏览器加载flexie.js,但是这是没有用的。
还存在另外一些问题。首先,flexie.js只会找那些没有前缀的CSS。但是Autoprefixer 不会为旧语法生成没有前缀的CSS,可能是因为浏览器根本用不上这些语法。
你可以通过修改flexie.js修复这些问题,但是你依旧走不出困境。在媒体查询中使用flexbox,Flexie.js会有很多bug,因为包含了一个硬编码版本的Selectivizr,和respond.js一起用时会无效。
在修复这些问题之前(如果可以修复),我能想到的唯一方法是创建一张专门针对IE8/9的样式表,在这张样式表中使用旧语法。
即使这样,你也不能只用flexbox就期望所有效果都很好。你绝对不可以使用自动间距。你必须要让布局尽量简单。我发现不可以让flexbox旧语法都可以达到新语法同样的效果,特别是用了跨浏览器解决方案之后。
但是如果你不用媒体查询,只要付出一点点关爱,你就可以让flexbox在IE8上正常工作了。
在示例代码中,你可以我打了补丁的flexie.js。我用最快速的方法让它起了作用,所以不要用它进行生产,帮大家一个忙,打一个真正的补丁,然后将它发给flexie.js的作者。
现在语法的跨浏览器解决方案
我们需要的是使用现代语法的跨浏览器解决方案。好消息是flexie.js的作者理查德·赫雷拉(Richard Herrera)正在改善它。但是直到现在,还远没有完成。
学习最新的flexbox语法
新版本的flexbox语法出来还不是很久,所以很多人对此也不是很熟悉。如果你想将flexboxl加入你的武器库,我有一些很好的资料推荐给你。
我为flexbox写了一些免费教程,你正在读的这篇文章恰好是这个系列的最新课程。如果你喜欢,可以点击这里获取剩余的文章。
用快速的开发周期打动你的客户。随心所欲地使用CSS布局,给你的客户看一个他们可以正常使用的程序。