[译] Houdini:也许是你未曾听过的最振奋人心的 CSS 进化

原文链接:Houdini: Maybe The Most Exciting Development In CSS You’ve Never Heard Of
更多译文将陆续推出,欢迎点赞+收藏+关注我的专栏,未完待续……

你是否曾经想要使用一些特别的CSS特性,却因为未曾得到所有浏览器的支持而选择放弃?又或者是,这些特性得到了所有浏览器的支持,但总会伴随着奇怪的bug,表现不一致甚至相互矛盾?如果这些事情都曾发生在你身上——我敢打赌——你应该关注一下Houdini。

Houdini是W3C的一项新的任务,其宗旨在于解决上面所说的问题。它计划通过提供一系列的API,使开发者得以自定义扩展CSS,并把这些样式直接放入浏览器的渲染引擎中渲染出来。

但这事实上到底意味着什么?这真的是一个好主意吗?以及它会如何帮助我们开发现代的和面向未来的页面呢?

在这篇文章中,我将尝试回答上述问题。在此之前,明白当今存在什么问题,以及需要做出什么改变,是非常重要的。待会我将更加详细地介绍Houdini是如何解决问题的,并将列出一些在目前开发过程中遇到的酷炫的特性。文章的最后,我会提供一些实实在在的能让我们这些web开发者为Houdini成为现实的做法。

Houdini想要尝试解决的是什么问题?

每当我撰写文章或者制作DEMO,用于展示一些新的CSS特性的时候,不可避免的总有人评论或者在Twitter留言说:“真是酷炫狂霸叼炸天!但糟糕的是在未来十年内我们都无法使用它们。”

就像上面那些负能量满满又毫无建设性的评论那样,我深以为然。在历史上,新特性的草案往往经过多年才被普遍接受。正因为如此,并且在纵观web的发展史后,让新特性草案真正成为CSS标准的唯一办法就是让其走一遍标准流程。


标准流程中的每一步

面对这所谓的标准流程我无力反抗,但必须承认这浪费了大量的时间!

比方说,flexbox第一次被提议是在2009年,但开发者们仍然在抱怨直到现在都无法使用它,因为只有少数浏览器支持这一特性。好在随着大部分浏览器都支持自动更新,这个问题正在慢慢得以改善;然而,即使拥有着现代浏览器,从草案到成为可用标准之间,依然存在着迟延。

有趣的是,这并非是web开发中所有领域都出现的问题。让我们看看Javascript是怎么做的:


Js中写polyfill的步骤

在这种情况下,一个方案从构思到在生产环境使用,往往只不过几天时间。我的意思是,在生产环境中我已经在使用async/await方法了,即使这个方法未被任何一个浏览器所支持!

你也可以感受到这两个社区的巨大情绪差异。在Javascript社区中,你会看到一些抱怨JS发展太快的文章。与之相反的,在CSS社区你会听到一些感叹,在能够真正使用之前,学习任何新的特性都是徒劳的。

那么,为什么我们不自己去写一些CSS的polyfill呢?

乍这么一想,写CSS的polyfill似乎是现成的答案。伴随着优秀的polyfill,CSS将会发展得跟Javascript一样快,对吗?

很可惜,这并没有那么简单。为CSS进行polyfill非常困难,更多的时候往往会毁掉所有的性能。

Javascript是一门动态语言,这意味着你可以用JS去polyfill它自身。也正因为它动态的特性,它是非常易于扩展的。从另一个角度来说,CSS几乎不能被自己所polyfill。在某些情况下,你可以通过构建的方法实现CSS的polyfill(POSTCSS就是干这个的);然而当你想要polyfill任何依赖于DOM结构的,或者某一元素样式或位置的东西的时候,你不得不在客户端运行你的polyfill逻辑。

不幸的是,浏览器很难实现这个需求。

下面的图片展示的是浏览器对于一个HTML文档从接收到渲染的基本过程。其中蓝色区域就是Javascript有能力作出控制的步骤:


Javascript在浏览器渲染进程中的控制权

这幅图挺让人沮丧的。作为一个开发者,你无法控制浏览器是如何将HTML和CSS解析为DOM 和 CSS 对象模型(CSSOM)的;无法控制整个渲染过程;无法控制浏览器是如何选择把元素渲染到DOM上面的,或者如何把内容填充到屏幕上展现给用户;你也无法控制浏览器是如何排版的。

你唯一能够完全控制的只有DOM这一块。在这种时候CSSOM是可用的;即便如此,引用Houdini网站的一句话,这是“蹩脚的,浏览器之间不一致的,缺乏论证的特性。”

举个例子,在如今浏览器中的CSSOM,不会告诉你跨域样式表的规则,并且很容易就会抛弃掉它看不懂的CSS语法或者声明——这意味着当你想要polyfill一些浏览器不支持的特性的时候,你无法使用CSSOM。取而代之的,你只能手动遍历DOM,找到