这一篇我来和大家讨论个原则: (避免在CSS中使用表达式)
最早的CSS是不支持所谓的表达式的,微软的IE从5.0开始引入了这种概念,意思是希望我们拥有定义动态的CSS样式的能力,详细的文章请参考,下面有一个简单的例子:
background-color: expression((new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
这里可以使用一个特殊的expression函数,其实这是一个javascript的函数。它可以进行根据一个表达式进行计算,动态地决定background-color的值。
看起来是一个相当不错的功能,但我们可能不会想到这个表达式会运算很多次(这个具体的次数可能远远超过你的想象)
我随便定义了一个界面,并添加了如下的样式定义
body {
}
打开之后,只是鼠标动来动去,或者滚动条上下拖动几下,就会执行1865次。如下图所示
很显然,这是很可观的一些成本。这还是比较简单的表达式,试想一下,如果有更加复杂的表达式呢?这些函数需要一次一次的执行,毫无疑问地会拖累页面执行的效率,乃至浏览器的性能。
正因为如此,不光是其他浏览器都不支持,同时w3c标准组织也不支持这种方式。鉴于此,微软方面也于2008年(彼时发布了IE 8)的时候,正式终止了对这种功能的支持。下面这篇文章是当时所发出的声明:
文中提到的三点不再支持CSS表达式的原因,显然是很中肯的(更加符合标准,更加有利于性能提升,以及减少受攻击面)
Why end support for expressions ?
- To comply with standards
- Expressions are proprietary to Internet Explorer and as such not interoperable.
- A common use-case for expressions was to fix IE bugs or to emulate those CSS 2.1 features not yet supported by the browser, for example, min-width and max-width. We have not only worked hard to fix these bugs in IE8 but our new layout engine supports the missing features natively.
- To improve performance
- Expressions evaluation has a high runtime cost; web performance experts like Steve Souders
- To reduce the browser attack surface
- Because they expose a script execution context, CSS expressions constitute a possible script injection attack vector.
那么,情况已经很清楚了,如果你根本不了解CSS表达式,那么恭喜你,你不需要再了解它了。如果你以前用过CSS表达式,而且对它还比较喜欢,那么我也希望你能慎重地考虑一下这条建议,并且毅然地选择放弃这种功能,拥抱标准吧。
好吧,你可能已经同意了我的提议,但是仍然有一个疑问,那么如果我们真的希望实现动态的CSS,怎么办呢?例如上面这个例子,我们希望根据当前的时间,来决定显示什么背景颜色。(小时为单数时显示一种颜色,为复数时显示另外一种颜色)。
你在想这个问题是吗?那我们为什么不像下面这么做呢?
$(function () {
$("body").css("background-color", (new Date()).getHours() % 2 ? "#B8D4FF" : "#F08A00");
});
我们不光发现调用次数少了,而且这种代码在所有主流浏览器都能实现一致的用户体验,何乐而不为呢?