2

原文:FLEXBOX IN THE REAL WORLD

flexbox 相当好用,但是现在就可以用flexbox并且让它支持到IE8吗?如果你跟着下面的步骤,现在就可以开始用flexbox啦。
_
我介绍flexbox已经有一段时间了,别人问得最多的问题是“什么时候flexbox能得到足够好的支持,可以用到实际的项目中?”

我总觉得flexbox在快速原型开发中有一席之地。但我也认为进行小小的规划,大多数人现在就可以将flexbox用在实际的产品中。

在这篇文章中,我们一起探索将flexbox用在产品中的条件、最佳的设计方案和兼容到IE8。

我们用的demo是我朋友正在开发的一个小项目的注册页。皮特在用BootStrap的栅格系统时遇到的一些布局问题,如果用flexbox就很容易解决,所以这是一个很好的例子。下面这个是我们将要创建的布局。

注册Demo

这个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下的效果。

footer Demo

场景#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布局,给你的客户看一个他们可以正常使用的程序。


对角另一面
1.4k 声望79 粉丝

踏在路上交叉点,你在对角另一面。