CSS 样式的优先级

2,019 阅读4分钟
原文链接: developer.mozilla.org

概念

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

如何计算优先级?

优先级是根据由每种选择器类型构成的级联字串计算而成的。他是一个对应匹配表达式的权重。

如果优先级相同,靠后的 CSS 会应用到元素上。

注意: 元素在文档树中的位置是不会影响优先级的。

优先级顺序

下列是一份优先级逐级增加的选择器列表:

  • 通用选择器(*)
  • 元素(类型)选择器
  • 类选择器
  • 属性选择器
  • 伪类
  • ID 选择器
  • 内联样式

!important 规则例外

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

一些经验法则:

  • Never 永远不要在全站范围的 css 上使用 !important
  • Only 只在需要覆盖全站或外部 css(例如引用的 ExtJs 或者 YUI )的特定页面中使用   !important
  • Never 永远不要在你的插件中使用 !important
  • Always 要优化考虑使用样式规则的优先级来解决问题而不是 !important
  1. 更好的利用 CSS 的级联属性
  2. 使用更多具体的规则。比如在你需要选定的对象元素前加上更多的元素,使选择的范围缩小,你的选择器就变得更有针对性,从而提高优先级:
    Text
    #test span { color: green }
    span { color: red }
    div span { color: blue }

无论你c​ss语句的顺序是什么样的,文本都会是绿色的(green)因为这一条规则是最有特殊性、优先级最高的。(同理,无论语句顺序怎样,蓝色(blue)的规则都会覆盖红色(red)的规则)

什么时候应该使用:

A) 一种情况

  1. 你的网站上有一个设定了全站样式的CSS文件,
  2. 同时你(或是你同事)写了一些很差的内联样式。

在这种情况下,你就可以在你全局的CSS文件中写一些!important的样式来覆盖掉那些直接写在元素上的行内样式。

活生生的例子比如:一些写得很糟糕的 jQuery插件里面使用的内联样式。

B) 另一种情况

#someElement p {
    color: blue;
}

p.awesome {
    color: red;
}

在外层有 #someElement 的情况下,你怎样能使 awesome 的段落变成红色呢?这种情况下,如果不使用 !important ,第一条规则永远比第二条的优先级更高

怎样覆盖掉 !important

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

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

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

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

td {height: 50px !important;}

更多关于important的帖子:

stackoverflow.com/questions/3…

stackoverflow.com/questions/9…

stackoverflow.com/questions/5…

stackoverflow.com/questions/1…

stackoverflow.com/questions/2…

:not 伪类例外

:not 否定伪类在优先级计算中不会被看作是伪类. 事实上, 在计算选择器数量时还是会把其中的选择器当做普通选择器进行计数.

这是一块CSS代码:

div.outer p {
  color:orange;
}
div:not(.outer) p {
  color: lime;
}

当它被应用在下面的HTML时:

This is in the outer div.

This text is in the inner div.

会在屏幕上出现以下结果:

This is in the outer div.

This text is in the inner div.

基于类型的优先级

优先级是根据选择器类型进行计算的. 在下面的例子中,属性选择器尽管选择了一个ID但是在优先级计算法则中还是根据其类型计算 .

有如下样式声明:

* #foo {
  color: green;
}
*[id="foo"] {
  color: purple;
}

将其应用在下面的HTML中:

I am a sample text.

最终会出现下面的效果:

I am a sample text.

因为即使选择的是相同的元素,但是 ID 选择器有更高优先级,所以第一条样式声明生效.

无视DOM树中的距离

有如下样式声明:

 body h1 {
  color: green;
}
html h1 {
  color: purple;
}

当它应用在下面的HTML时:



  

Here is a title!

浏览器会将它渲染成:

Here is a title!