CSS的一点儿事情

再看next这个主题时因为一个首页的

1
<p></p>

标签居中的问题,改了下编译出的CSS,因为需要首页和文章页的大部分结构和属性都一样。不得不写成这个样子:

1
2
3
.container.one-collumn.sidebar-position-left.page-home div[itemprop="articleBody"] {
text-align: center !important;
}

首页和其他页面区分的有page-home以及每个文章块的下方大按钮值。所以有想,CSS选择器要是能选上方的多好。
事实上CSS本身不能,无法实现的原因是w3c未提供相关的选择器,原因是因为这样会引起回溯。

作者:贺师俊
知乎链接

如何参与标准请看@一丝君的答案,特别推荐你加入W3C中文兴趣小组的邮件列表。

这里仅谈一下你想到的几个selector。如@程劭非 所说,CSS一直几乎没有这样的选择器,是因为这样的选择器会导致回溯。

浏览器最初设计的时候就考虑了渐进显示,也就是整个文档加载了多少就显示多少内容,而不用等整个下载完。即使在主流网速比18年前互联网早期时代要快超过500倍,我们仍然会遇到很大的文档(你们这些恨不得把全站所有链接还有各种广告都塞进来的产品经理,我说的就是你们!还有前端屌丝,别偷笑,你们这些帮凶!),或卡顿的情况(感谢伟大的墙对此也有贡献)。

渐进显示在CSS上的原理就是一个节点所适用的样式只取决于它和它之前的节点(父节点、它之前的兄弟节点)的性质。而你所设想的那些selector则恰好相反。也就是当浏览器解析到一个新节点时,可能改变之前节点所适用的样式——因而要求在解析一个新节点后,得回头重新计算之前节点所匹配的样式,此即所谓“回溯”。在最坏的情况下所导致大量的重新计算和reflow,可以相当于重新render整个网页。

所以CSS直到2.1都没有任何可能引起回溯的selector。但是selector 3就开了口子了。比如:last-child。考虑如下rule:

1
div:last-child { display:none }

CSS2的所有selector在

的start tag结束后就确定是否匹配了,但是对于:last-child伪类,要判断这条规则是否适用,至少是在
之后再读入一个tag才行(是父元素的end tag则匹配,反之不匹配)。假设一个div是整个页面的container,那么就导致在页面没有加载完时能看见div(前提是浏览器已经渐进显示了部分内容),而在加载完后就看不见了。

类似的,考虑 x:empty ,比 :last-child 好点,在解析到 时就可以确定了,而不用再读一个tag。
而 :nth-last-child() 则就比 :last-child 要更困难,得等整个父元素结束。

但是即使这些 selectors 仍然可以确定出具体的点,selector 4则有一些无法确定何时回溯的选择器。比如 reference combinator。

所以JQuery大法好,以上。