[译] 渐进加强的 CSS 布局:从浮动到 Flexbox 到 Grid

今年早些时候,大多数主流浏览器都支持了 CSS Grid 布局。天然地,规范也成为了大小会议的热门话题之一。在参与了一些关于 Grid 布局和渐进加强的讨论后,我认为使用它仍是有很大的不肯定性。我听到一些颇有趣的问题和发言,我想在这篇文章中讨论讨论。css

最近几周听到的声明和问题

  • “我何时能够开始使用 CSS grid 布局?”
  • “还须要好几年我才能在实际项目中使用 CSS Grid 布局,这太扯淡了。”
  • “为了使用 CSS Grid 布局,网站须要 Modernizr 吗?”
  • “若是我如今想使用 CSS Grid,那我须要为个人网站作两三个版本。”
  • “渐进加强在理论上听起来不错,但我认为在实际项目中不可能实现。”
  • “渐进加强的成本是多少?”

这些都是很好的问题,并非全部的都很容易回答,但我很乐于分享个人一些方法。CSS Grid 布局模块是响应式设计中最使人激动的发展之一。若是它对咱们和咱们的项目有意义,咱们应尽快去用好它。html

Demo: 渐进加强布局

在详细阐述我对上述问题的想法以前,我想介绍一下我作的一个小的 demo前端

注意: 最好在配备有大屏幕的设备上打开上面这个 demo。你用手机打开的话,啥也看不见。
react

使用了 Flexbox 和 CSS Grid 的渐进加强的 CSS 布局
使用了 Flexbox 和 CSS Grid 的渐进加强的 CSS 布局

示例网站的主页,具备可调节的滑块,可在不一样的布局技术之间进行切换。
当你打开这个 demo, 你会发现本身在一个基本布局的网站的主页上。您能够调整左上角的滑块以加强您的体验。布局从很是基本到基于浮动的布局,再转换为 基于 flexbox 的布局,最后是基于 CSS Grid 的布局。

它不是最美丽或最复杂的设计,但它足以显示基于浏览器功能的网站能够采用哪些形态。android

此演示页面使用 CSS Grid 布局构建,不使用任何前缀属性或 polyfills。它对于 Internet Explorer(IE)8,极限模式下的 Opera Mini,UC 浏览器和当前最流行的现代浏览器的用户来讲,都是能够访问的。若是你不期待在全部浏览器中都看到彻底相同的效果,那么你如今彻底可使用 CSS Grid 布局。可是指望使用 CSS Grid 在全部浏览器中都看到彻底相同的效果是如今没法实现的。我很清楚,这种状况并不彻底取决于咱们的开发人员,可是我相信若是客户明白其中的好处(面向将来的设计,更好的可访问性和更高的性能),咱们的客户会很愿意接受这些差别。除此以外,我相信咱们的客户和用户 —— 感谢响应式设计 —— 已经了解到,网站在每一个设备和浏览器中看起来都不同。ios

在接下来的部分中,我将向你展现如何构建 demo 的部份内容,以及为何有些效果只在 box 外有效。css3

边注:,为了让这个 demo 支持 IE 8,我不得很少添加几行 JavaScript 和 CSS(一个 HTML 5 垫片)。我没办法,由于 IE 8+ 听起来比 IE 9+ 更使人印象深入。git

CSS Grid 布局和渐进加强

咱们一块儿来深刻了解我如何在页面中心创建“四级加强”组件。github

HTML

我将全部项目按逻辑顺序放入到 section 中。该部分的第一个 section 中是标题,其次是四个小节。假设它们表明单独的博客帖子,我把它们中的每个都包含在一个 article 标签中。每篇文章由一个标题(h3)和一个图像连接组成。我在这里使用 picture 元素,由于我想在视口足够宽的状况下,为不一样的用户提供不一样的图像。在这,咱们已经有了良好的渐进加强的第一个例子。若是浏览器不理解 picturesource,它仍然会显示 img,这也是 picture 元素的一个子元素。web

<section>
  <h2>Four levels of enhancement</h2>
  <article><h3>No Positioning</h3><a href="#">  <picture>    <source srcset="320_480.jpg" media="(min-width: 600px)">    <img src="480_320.jpg" alt="image description">  </picture></a>
  </article>
</section>复制代码

浮动加强功能

用 float 构建的演示页面的一个组件
用 float 构建的演示页面的一个组件

全部的项目都在“四级加强”组件中,向左浮动。

在较大的屏幕上,若是全部项目彼此排列,则此组件的效果最好。为了支持不了解 flexbox 或 grid 的浏览器,我将其设为浮动,给它们设置了必定的 sizemargin,并在最后一个浮动项目以后清除浮动。

article {
  float: left;
  width: 24.25%;
}

article:not(:last-child) {
  margin-right: 1%;
}

section:after {
  clear: both;
  content: "";
  display: table;
}复制代码

Flexbox 加强功能

用 flexbox 布局构建的演示页面的一个组件
用 flexbox 布局构建的演示页面的一个组件

“四个层次的渐进加强”中的全部项目都因 flexbox 的加入而获得了提高。

在这个例子中,我实际上不须要使用 flexbox 来加强组件的整体布局,由于浮动已经完成了个人需求。在设计中,标题在图像的下边,这能够经过 flexbox 实现。

article {
  display: flex;
  flex-direction: column;
}

h3 {
  order: 1;
}复制代码

使用 flexbox 从新为各个项目进行排序时,咱们必须很是谨慎 咱们应该仅将其用于视觉上的变化,并确保从新排序不会改变键盘或屏幕阅读器用户的体验。

Grid 加强功能

用 grid 布局构建的演示页面的一个组件
用 grid 布局构建的演示页面的一个组件

“四个层次的渐进加强”中的全部项目都因 CSS Grid 的加入而获得了提高。

一切看起来都不错,但标题仍然须要进行一些定位上的调整。有不少方法能够将标题放在第二个项目的正上方。我发现最简单、最灵活的方式是使用 CSS Grid 布局。

首先,我画了一个四列的网格,在父级容器上有一个 20 像素的凹槽。

section {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-gap: 20px;
}复制代码

由于全部文章的宽度都是 24.25%,因此我为支持 CSS Grid 的浏览器从新设置了这个属性。

@supports(display: grid) {
  article {width: auto;
  }
}复制代码

而后,我把标题放在第一行和第二列。

h2 {
  grid-row: 1;
  grid-column: 2;
}复制代码

为了去掉 Grid 的自动 auto-placement,我还将第二个 article 显式地放在第二行和第二列(标题下)。

article:nth-of-type(2) {
  grid-column: 2;
  grid-row: 2 / span 2;
}复制代码

最后,由于我想删除标题和第二个项目之间的间距,全部其余项目必须跨两行。

article {
  grid-row: span 2;
}复制代码

就是这样。你能够在 Codepen 上看最终的布局5

若是我须要让这些代码支持 IE 9+,那么咱们将总共须要八行代码(其中三行其实是 clearfix,而且是可重用的)。当你使用前缀的时候也要对比一下。

article {
  float: left;
  width: 24.25%;
}

@supports(display: grid) {
  article {width: auto;
  }
}

section:after {
  clear: both;
  content: "";
  display: table;
}复制代码

这只是一个简单的例子,而不是一个完整的项目,我知道一个网站有更复杂的组件。可是,想像一下,在全部的浏览器中构建一个布局效果几乎同样的项目须要多长时间。

你不须要覆盖一切

在前面的例子中,width 是惟一一个必须重置的属性。关于 grid(和 flexbox,顺便说一下)的一个重要的事儿是,若是某些属性被应用于 flex 或 grid 的项目内部,它们将失去原来的做用。例如 float,若是它应用于的元素在 grid 容器内,则不起做用。对于其余一些属性也是如此:

  • display: inline-block
  • display: table-cell
  • vertical-align
  • column-* 属性

更多内容请点击查看 Rachel Andrew 写的 “Grid 回退和覆盖。

展现 CSS 功能查询支持状况的表格
展现 CSS 功能查询支持状况的表格

几乎每一个主流浏览器都支持 CSS 功能查询。(查看大图)。

若是你必须使用属性覆盖,那就是用 CSS 功能查询。在大多数状况下,你只须要覆盖 widthmargin 等属性。 功能查询的支持状况很是好,而且最好的是每一个浏览器都支持网格。在这你不须要 Modernizr

此外,你不须要将全部的 grid 属性都放在功能查询中,由于旧的浏览器会简单的忽略他们不了解的属性和值

在我写这个 demo 的时候,对我来讲惟一感到有点棘手的是当有一个 flex 或 grid 容器使用了 clearfix 的。包含内容的伪元素也能够变为 flex 或 grid 项。它可能会,也可能不会影响你;只要知道它就行了。做为替代方案,你可使用 overflow:hidden 来清除父级,若是这适用于你的话。

衡量渐进加强的成本

浏览器已经为咱们作了不少渐进加强的工做。我已经提到 picture 元素,它返回到 img 元素。另外一个例子是 email 字段,若是浏览器不明白,它将返回一个简单的 text 字段。另外一个例子是我在 demo 中使用的调节滑块。在大多数浏览器中,它会被渲染为可调节的滑块。例如,IE 9 中不支持输入类型 range,但它仍然可使用,由于它返回一个简单的 input 字段。用户必须手动输入正确的值,这不太方便,但它能够正常工做。

Chrome 和 IE 9 中的输入范围调节效果的比较
Chrome 和 IE 9 中的输入范围调节效果的比较

比较在 Chrome 和 IE 9 中如何呈现 range 输入类型。

有些东西是浏览其所关注的,其余的则须要由咱们负责

在准备 demo 的时候,我意识到,真正了解 CSS 是很是有帮助,而不只仅是写一些属性,但愿可以在浏览器中得到最佳的效果。越了解浮动,flexbox 和 grid 的工做原理,以及您对浏览器的了解越多,越容易实现渐进加强。

成为一个了解 CSS 的人,而不只仅是使用 CSS 的人,将为你在工做中带来巨大的优点。

Rachel Andrew16

此外,若是渐进加强功能已经深刻整合到您制做网站的过程当中,那么很难说会有多少额外的付出,由于这就是你作网站的方法。亚伦·古斯塔夫森(Aaron Gustafson)分享了他在文章“渐进加强的实际成本”和 “Relative Paths podcast” 中所作的一些项目的几个故事。我强烈建议你阅读并学习他的经验。

Resilient Web Development

你的网站和你测试的最弱的设备同样强大。

Ethan Marcotte

渐进加强可能在一开始须要一点工做,可是从长远来看能够节省时间和金钱。咱们不知道用户接下来会使用哪些设备,操做系统或浏览器访问咱们的网站。若是咱们为不是太好的浏览器提供可访问和可用的体验,那么咱们就正在构建具备弹性的产品,并为意想不到的发展作好准备。

摘要

我有一种感受,咱们中的一些人忘记了咱们的工做是什么,甚至可能忘记咱们实际作的“仅仅”是一份工做。咱们不是摇滚明星,忍者,工匠或大师,咱们所作的最终是将内容放在网上,让人们尽量轻松地消费。

内容是咱们建立网站的缘由。

Aaron Gustafson

这听起来很无聊,我知道,但不必定是这样的。咱们可使用最热门的尖端技术和花哨的技术,只要咱们不忘记咱们在为谁作的网站:用户。咱们的用户不同,也不使用相同的设备,操做系统,浏览器,互联网提供商或输入设备。经过提供最基本的版本开始,咱们能够从现代网络中得到最佳效果,而不会影响可访问性。

展现 CSS 功能查询支持状况的表格
展现 CSS 功能查询支持状况的表格

几乎每一个主流浏览器都支持 CSS 功能查询。(图片:我可使用)(查看大图)。

Grid,例如,几乎在每一个主流浏览器中都获得了支持,咱们不该该等待好多年,直到覆盖率达到 100% 才在实际项目中使用它,由于那根本不存在。仅仅是由于 web 本就不是那么玩的。

Grid 很是好用。如今就开始使用吧!

截图

如下是各类浏览器的 demo 页面的截图:

Internet Explorer 8, Windows 7

Internet Explorer 9, Windows 7

Internet Explorer 10, Windows 7

Internet Explorer 11, Windows 8

Opera Mini 42 (Extreme), Android 7

UC Browser 11, Android 7

相关资料和深刻阅读

感谢个人导师 Aaron Gustafson 对我创做本文的帮助,感谢 Eva Lettner 的校对,感谢 Rachel Andre 无数的帖子、demo 和建议。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOSReact前端后端产品设计 等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索