实际上,最近的selector 4的草案是支持的。不仅是你给的例子(compound selector)支持,实际支持selector list(即所有选择器)。
【以下是我的主观看法,不保证准确,谨供参考。如需验证,请自行查阅w3c mailing list记录,或写邮件咨询spec的编辑,比如
fantasai和
Tab Atkins Jr.。】
过去(selector 3规范)确实仅支持单个simple selector。
我们需要理解,技术上可以做到不代表就应该直接上。
首先我们应该考虑需求,即实际的use cases。单个simple selector其实已经满足了大量需求了。对于简单的compound selector的需求,比如`a:not(.b.c)`,可以写作`a:not(.b):not(.c), a.b:not(.c), a.c:not(.b)`。题主写的`img:not(.abc[alt][href])`(这里href估计是题主的笔误,因为img上只有src属性)也可以转写。当然,这比较麻烦,且如果多的话,很容易出现组合爆炸。不过当初连简单的:not都没有,人民群众并不习惯逆向思维,更复杂的需求还没有被发掘,也就是并没有很多use cases。
其次,我们是希望新特性出来非常慢但是一步到位,还是先出一部分特性用起来呢?总的来说,后者更好。因为更快出可用的新特性,大家可以更快试验,也就可以更快的给出反馈,厂商可以更快的发现和修复bug,标准工作组可以更快地确认真实的use cases,确认spec的设计是可行和合理的。此外,小步走可以在工程上控制复杂度,避免出现步子迈得太大扯到蛋。(比如CSS2就是一个反例。当初标准过于复杂,就不可能有足够完善和完全的实现,各浏览器实现存在各种bug不说,更有许多是spec本身存在bug、未定义或含糊不清的地方。)当然,“小步走”的前提是你本身是有设计有规划的。现在一些公司所谓的“小步走”实际是“快糙猛”,请大家注意甄别,千万别混为一谈。【PS. “小步走”也绝不等于“摸着石头过河”——所谓“摸石头过河”是一种非常恶心的做法,因为其实质是忽悠大家连救生圈都不带就下河,你若渡河成功算领导高瞻远瞩指挥有方,你若不幸淹死就成了领导嘴里不可避免要付出的代价然后被遗弃。】
具体到`:not`,仅支持单个simple selector意味着可将:not简单视为一种新的simple selector,从工程师的角度看,可以完全不改动selector引擎的原有设计和实现,实现起来很容易。而支持复杂的:not或者:matches则意味着必须支持一种以前从未有过的嵌套结构,虽然看起来也不是很难,但数据结构、匹配流程、优化算法很可能全都要改,实际工作量大许多。
此外,selector是有性能要求的。这是为什么在css3 selector之前没有任何需要回溯计算的选择器。:not也存在性能上的问题。不难看出,其内部如果是compound selectors,性能和不带:not的相同compound selectors并不会有什么差别。但是如果里面有combinator,这个复杂度就不好判断了。所以之前草案一直规定css匹配时,:not、:matches等只能包含compound selectors,只有调用js的selectors api时才支持完整selectors。不过最近的草案去除了大部分限制,只保留了对:has的限制。这应该是浏览器厂商的工程师已经完成了对性能影响的评估——这个事情不是光靠嘴巴说说的,一定是需要真的实现出来然后测试验证的。这也是为什么这些新的特性不是一蹴而就的。
以上。