使用 Flexbox:混合旧的和新的以获得最佳浏览器支持

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 $200 免费信用额度!

Flexbox 非常棒,并且肯定是未来布局的一部分。语法在过去几年中发生了很大变化,因此出现了 “旧”和“新” 语法。但是,如果我们将旧的、新的和介于两者之间的语法编织在一起,就可以获得不错的浏览器支持。特别是对于一个简单且可能是最常见的使用场景:顺序控制网格

HTML

一个语义上无意义的包装器围绕着三个主要区域,并将设置 flexbox 上下文。每个区域都用语义标记起来,并将被转换为列。

<div class="page-wrap">
  
  <section class="main-content" role="main">
    Main content: first in source order
  </section>
  
  <nav class="main-nav" role="navigation">
    Links
  </nav>
  
  <aside class="main-sidebar" role="complementary">
    Sidebar
  </aside>
    
</div>

最终结果看起来像这样

Flexbox 上下文

我们需要将列的容器设置为 flexbox 显示上下文。仅通过这样做,此元素的所有直接子元素都会成为 flex 项目。无论它们之前是什么,现在都是 flex 项目。

我们马上需要将旧的、新的和过渡的语法编织在一起。顺序在这里很重要。由于 display 属性本身没有前缀,我们需要确保我们没有用旧的语法覆盖新的语法,以便仍然(可能永远会)支持这两种语法的浏览器。

.page-wrap {
  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+ */
 }

控制列宽

我们的目标是 20% / 60% / 20% 的网格。

第一步是将我们的主要内容设置为 60%。
第二步是将外部侧边栏设置为平均填充剩余空间。

我们再次需要将旧的、新的和过渡的语法编织在一起。

.main-content {
  width: 60%;
}
.main-nav,
.main-sidebar {
  -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+ */
}

在新语法中,设置侧边栏的宽度不是必需的,因为它将平均填充剩余的 40%,使它们都成为 20%。但我发现没有设置它会导致旧语法出现一些宽度折叠。

列重新排序

我们希望主要内容在视觉上出现在中间,但在源代码顺序中排在第一位。在 flexbox 中很容易,但当然我们需要将新的、旧的和过渡的语法编织在一起。

.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;
}

浏览器支持

如果您执行所有这些编织,您将获得

  • Chrome 任何版本
  • Firefox 任何版本
  • Safari 任何版本
  • Opera 12.1+
  • IE 10+
  • iOS 任何版本
  • Android 任何版本

最大的限制因素当然是 IE,但除此之外,它非常好。如果您正在制作网站的移动特定版本,您的情况会更好。如果有人可以在 Windows Phone 上测试它,请告诉我。

Firefox 19- 有一些错误,您需要注意它。例如,在这个演示中,我无法找到一种方法来强制侧边栏实际上是 20%。它们只是折叠到内部内容的宽度,这有点随意,因为它是文本。我还需要在主要内容 (60%) 上使用 -moz-box-flex: 1;,否则它会伸展到最宽段落的宽度,就像它具有 white-space: nowrap 一样,这对我来说简直不可思议。

演示

在 CodePen 上:

Check out this Pen!

需要更多关于 Flexbox 的详细信息?

查看我们的完整指南。