CSS优先级

最近一段时间比较闲,没有多少课,没有多少考试,也没有多少项目,有空逛逛微博逛逛知乎,看看大牛们的状态,还有互联网上的各种撕逼各种黑。看到大牛们在微博、知乎和Github上的文章,通常文章的一部分还能懂点,一部分就要好好理解消化一下,再有一部分就要查查这个名词是什么玩意儿,这个概念又是什么玩意儿,摩擦啊,发现自己很low啊,整个人都 not ok 了。

既然遇到不懂的,那就得去查阅资料,看看文档(此处装个X),CSS优先级以前只是模糊的懂一些,看了文档之后会了解的更深刻一些。

首先来看一下优先级的概念:

优先级是浏览器是通过判断哪些属性值与元素最相关以决定并应用到该元素上的。优先级仅由选择器组成的匹配规则决定的。

那么如何计算优先级呢?

优先级是根据由每种选择器类型构成的级联字串计算而成的。他是一个对应匹配表达式的权重。通俗的可以把他比喻成天平,哪个选择器的权重最大,则元素就对应该选择器下的样式规则,而如果优先级相同,靠后的CSS会应用到元素上,也就是说同样的优先级,位置靠后的会覆盖位置靠前的。注意: 元素在文档树中的位置是不会影响优先级的

优先级顺序(优先级逐级增加的选择器列表)

  • 通用选择器
  • 标签选择器
  • 类选择器
  • 属性选择器
  • 伪类
  • ID选择器
  • 内联样式

有一个简单的运算规则,在上述列表中,相邻两个选择器之间的权重相差一个数量级,求得选择器的总权重后比较即可。那十个标签选择器的权重和一个类选择器的权重是一样的啊?别这样算,用十个标签选择器也是够了,权重相差一个数量级只是意思一下,具体意思是如果选择器中有数量级差别的话,那级别高的直接KO掉了低的。

!important规则

当!important规则被应用在一个样式声明中时,该样式声明会覆盖CSS中任何其他的声明,无论它处在声明列表中的哪里。尽管如此,!important规则还是与优先级毫无关系。使用!important不是一个好习惯,因为它改变了你样式表本来的级联规则,从而使其难以调试。

一些经验法则:

  • Never 永远不要在全站范围的CSS上使用!important
  • Only 只在需要覆盖全站或外部CSS(例如引用的ExtJs或者YUI)的特定页面中使用!important
  • Never 永远不要在你的插件中使用!important
  • Always 要优化考虑使用样式规则的优先级来解决问题而不是!important

什么时候应该使用!important

  • 项目里有一个设定了全站样式的CSS文件,同时某某写了一些很差的内联样式(一些写得很糟糕的 jQuery插件里面使用的内联样式)。
  • 在外层有ID选择器的情况下,使用!important残忍覆盖

总之就是你用各种选择器搞定不了的时候,放大招吧!话又说回来,谨慎使用!important大招。

怎样覆盖掉 !important

很简单,你只需要再加一条!important的CSS语句,将其应用到更高优先级的选择器(在原有基础上添加额外的标签、类或ID选择器)上;或是保持选择器一样,但添加的位置需要在原有声明的后面(优先级相同的情况下,后边定义的会覆盖前边定义的)。

一些拥有更高优先级的例子:

1
2
3
table td    {height: 50px !important;}
.myTable td {height: 50px !important;}
#myTable td {height: 50px !important;}

或者使用相同的选择器,但是置于已有的样式之后:

1
td {height: 50px !important;}

总之,更好的利用CSS的级联属性,使用更多具体的规则。比如在你需要选定的对象元素前加上更多的元素,使选择的范围缩小,你的选择器就变得更有针对性,从而提高优先级。

Tips:

  • :not伪类例外,:not否定伪类在优先级计算中不会被看作是伪类
  • 基于类型的优先级,优先级是根据选择器类型进行计算的
  • 无视DOM树中的距离

参考来自Mozilla开发者网络 MDN>Web 技术文档>CSS>优先级

Fork me on GitHub