渐进增强的CSS布局:从Float到Flex到Grid

96
alixwang
2017.08.03 23:56* 字数 2395

本文翻译自Progressively Enhancing CSS Layout: From Floats To Flexbox To Grid

在今年早些时候,桌面主流浏览器都支持了CSS Grid布局.所以Grid布局成了这段时间的热门话题。在听了不少关于grid和渐进增强的话题后,我认为在现阶段使用他还存在一些不确定性的问题,我将在本文中解答我所听到的一些有趣的问题。

这几个星期以来我所听到的一些观点和问题

  • 我什么时候能用grid布局?
  • 得在几年后才能在生产环境中用上grid布局这实在是很糟糕
  • 我需要用Modernizr库来让浏览器支持grid布局吗?
  • 如果我想在网站中运用grid布局那么不得不编写两到三个不同的版本
  • 渐进增强在理论上听起来不错,但是我不认为他能运用在实际项目中
  • 渐进增强的成本是多少?

以上都是一些精彩的提问,而且不容易回答,但是我非常乐于分享我自己的观点。CSS grid布局是在自适应布局后最令人兴奋的css特性。如果gird布局对我们自身和我们的项目有作用的话我们应该尽最大的努力去弄明白他。

Demo:渐进增强布局

在阐述上面的问题和说法之前我将展示一些我做的小demo给大家看。
Disclaimer:最好在电脑或者大屏幕上打开,在手机上打开这个例子没什么意义

The home page of an example website, with an adjustable slider to switch between different layout techniques.

当你打开这个demo的时候你会发现网站在一个基础的布局之下,你可以调节页面左上角的滑块去增强页面的体验,页面将从基础布局到float到flex然后到grid布局。
这不是一个非常漂亮和复杂的设计,但是这个例子已经可以说明网站的外形可以根据浏览器的能力在定制。
这个demo页没有用到任何的私有前缀和腻子脚本,它能够被IE8+,极限模式下的opera mini 还有UC浏览器访问,当然还有现代浏览器,如今你可以很好的运用Grid布局在你的网站上,只要你不是要求页面在每个浏览器上都有绝对相同的呈现效果,这个在现在是无论如何也做不到的。我知道使用Grid布局与否不是取决于我们开发者但是我相信如果我们的客户了解(面向未来设计,更好的可访问性和性能)的话他们是非常乐于接受在不同浏览器上的表现差别的。正是基于此我认为我们的客户和用户能够理解网站在不同的浏览器和设备上会有不同的展现效果(得益于自适应布局)

备注:我必须添加一些JS和CSS来让页面支持IE8,我没法拒绝这个因为IE8+听起来比IE9+更令人影响深刻

CSS Grid 布局和渐进增强

让我们深入了解一下我是怎么在页面中构建一个“四级增强”的组件

HTML
我开始把所有的项目按照逻辑顺序放入一个<section><section>的第一部分是头部,接下来是四个小节。假设它们代表一个单独的博客文章,我把它们包裹在一个<article>标记中,每个<article>由一个h3标签和一个图片链接组成。这里我试用了<picture>标签因为我想让拥有足够宽视口的用户提供不同的图片,在这里,我们已经有了第一个渐进增强的基础例子。如果浏览器不能识别<picture><source>标签,那么浏览器照样能识别到picture标签里面的img标签。

<section>
  <h2>Four levels of enhancement</h2>
  <article><h3>No Positioning</h3><a href="#">  <picture>    <source srcset="320_480.jpg" media="(min-width: 600px)">    ![](480_320.jpg)  </picture></a>
  </article>
</section>

FLOAT ENHANCEMENTS

All items in the “four levels of enhancement” component, floated left

在大屏上,如果每项都和其他项相邻布局那么这个组件能够表现良好。这个实现主要是为了那些不支持flex和grid布局的浏览器所做,让它们浮动并给他们一个大小和一些margin,在最后一个浮动后清楚浮动。

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

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

section:after {
  clear: both;
  content: "";
  display: table;
}

**Flexbox Enhancements **

All items in the “four levels of enhancement” enhanced with flexbox

In this example, I actually don’t need to enhance the general layout of the component with flexbox, because floating already does what I need. In the design, the headings are below the images, which is something that’s achievable with flexbox.

在这个例子中,其实我不需要用flex布局渐进增强,因为浮动布局完全能实现我想要的效果。在设计稿中,heading是在图片下面的,这是flex布局能实现的。

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

h3 {
  order: 1;
}

当我们在flex布局时重新排列元素顺序时必须非常谨慎,我们因该只在视觉变化时使用它,而且要保证重新排序不会对键盘使用和屏幕阅读器使用者造成影响。
Grid Enhancements

All items in the “four levels of enhancement” enhanced with CSS grid

现在所有的一切看起来都十分完美,但是标题还是需要进行一些定位,这里有很多方法让标题位于第二个的上面,最简单也是最灵活的方法就是使用grid布局。
首先我们画出四列网格,并且在容器中留出20像素的间距。

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

因为所有的文章都有24.25%的宽度,为了让浏览器理解grid我重新设置这个属性。

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

接下来,我把标题放在第一行的第二列。

h2 {
  grid-row: 1;
  grid-column: 2;
}

为了避免grid的自动排列,我还将第二个文章明确地放在第二行和第二列(标题下)。

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

最后,为了删除标题和第二个项目之间的差距,所有其他项目必须跨两行。

article {
  grid-row: span 2;
}

你可以在codepen上看到这个例子。
为了让这些代码能在IE9+中运行我提取了额外的代码,最终我们得到了八行代码(其中的三个是为了clearfix和重用。比较一下你用浏览器前缀所需的开销。

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

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

section:after {
  clear: both;
  content: "";
  display: table;
}

我知道这只是一个简单的例子而不是一个完整的项目,而且我们知道一个网站拥有比这个例子更加复杂的组成结构。但是,构建一个在所有各种浏览器中看起来像素完美相同的布局将需要多少时间。
你不必重写所有的东西
在前面的例子中,我们仅仅重置了width属性。关于网格(和flexbox,顺便说一下)的一个重要的事情是,如果某些属性被应用于flex或grid项目,它们将失去其原有的作用。例如,如果应用的元素在网格容器内,则float将不起作用。对于其他的一些属性也是如此。

display: inline-block
display: table-cell
vertical-align
column-* properties

CSS feature queries are supported in every major browser. (Image: Can I Use) (View large version)

如果您必须覆盖属性,请使用功能查询。在大多数情况下,您只需要覆盖宽度或边距等属性。对功能查询的支持是非常好的,最好的部分是每个浏览器都支持grid。你不需要Modernizr来做兼容。
此外,您不必将所有网格属性放在功能查询中,因为较旧的浏览器将简单地忽略不了解的属性和值。
衡量渐进增强的成本
浏览器已经为渐进增强做了很多。就像我提到的picture元素,如果浏览器不认识它,那么会回退到了img元素。另一个例子是电子邮件输入字段,如果浏览器不明白,则返回到简单的文本输入字段。在大多数浏览器中,它被渲染为可调节的滑块。例如,IE9不支持输入类型范围,但仍然可以使用,因为它返回到简单的输入字段。用户必须手动输入正确的值,这不太方便,但它可以正常工作。
Comparison of how the range input type is rendered in Chrome and IE 9

一些事情由浏览器来解决而剩下的由我们自己解决
在准备演示时,我意识到,真正了解CSS非常有帮助,而不仅仅是在浏览器中投掷属性,希望能够获得最佳效果。越了解浮动,flexbox和网格的工作原理,以及您对浏览器的了解越多,越容易设计出渐进增强的网站。

Becoming someone who understands CSS, rather than someone who just uses CSS, will give you a huge advantage in your work.
Rachel Andrew

此外,如果渐进式增强已经深入整合到您制作网站的过程中,那么很难说多少额外的成本,因为这很好,那就是您如何制作网站。AaronGustafson分享了他在“The True Cost of Progressive Enhancement”和"Relative Paths podcast"播客中所做的一些项目的几个故事。我强烈建议您听取并阅读他的经历。
灵活的网络开发

Your website’s only as strong as the weakest device you’ve tested it on.
Ethan Marcotte
渐进式增强可能会在一开始就涉及到一些工作,但是从长远来看可以节省时间和金钱。我们不知道用户接下来会使用哪些设备,操作系统或浏览器访问我们的网站。如果我们为不太有能力的浏览器提供可访问和可用的体验,那么我们正在构建具有弹性的产品,并为新的和意想不到的发展做好准备。

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

Content is the reason we create websites.
Aaron Gustafson

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

CSS grid layout is supported in almost every major browser. (Image: Can I Use) (View large version)

例如,几乎每个主要浏览器都可以使用网格,我们不应该等待更多的时间,直到覆盖率达到100%才能在生产中使用它,因为它将永远不会存在。这不是网络的工作原理。

参考链接

前端学习
Web note ad 1