CSS 层叠和选择器优先级怎么比较?:is、:where 有什么特殊之处?
先理解原理和示例,再练习完整口述与追问。
回答要点
先看来源、重要性与层,再比较 specificity;ID/类/元素分列比较;行内样式单独理解;:is 取参数最大值,:where 为零。
原理拆解
最终样式不是只比较选择器有多长。浏览器先过滤不适用的规则,再按来源、是否 important、层叠层等层叠条件比较;处于可以比较的同级规则,才进一步比较选择器优先级,之后还可能涉及作用域接近程度与出现顺序。!important 改变层叠重要性,不是给某个选择器凭空加一个无限大分数。
普通选择器按 ID 数、类/属性/伪类数、元素/伪元素数依次比较,不是把它们当十进制相加,所以很多类也不能简单抵消一个 ID。:is()、:not()、:has() 本身不额外贡献一列,它们的参数中最高优先级会参与计算;:where() 连同参数的优先级始终为零,适合定义容易被业务样式覆盖的基础规则。
在作者的普通样式中,未分层规则通常高于层中的普通规则,同为层内普通规则时后声明的层更高;important 规则的层顺序会反转。普通行内样式通常胜过普通样式表规则,但不能因此断言它永远最高,important、用户样式和过渡等还受更完整的层叠规则影响。实际排查先看 DevTools 的 Computed 和被划掉的声明,再检查选择器、继承、加载顺序、层与样式隔离。
参考:MDN Specificity。
示例与推演
比较 .panel .item 与 #root .item 时,先确认两条规则处在可比较的来源、层和重要性,再按 ID/类/元素的元组比较。:where(#root) .item 的 where 部分贡献零;:is(.a,#root) .item 会受到参数中 ID 优先级影响,不能只数最终匹配的某个分支。
易错点
important 不会修复错误选择器、继承方向或加载失败。调试用 Computed 查看最终来源,避免对无效规则不断加更长选择器。
参考回答可直接练习口述
最终样式不是只比较选择器有多长。浏览器先过滤不适用的规则,再按来源、是否 important、层叠层等层叠条件比较;处于可以比较的同级规则,才进一步比较选择器优先级,之后还可能涉及作用域接近程度与出现顺序。!important 改变层叠重要性,不是给某个选择器凭空加一个无限大分数。