CSS 技巧篇(五):理解CSS优先级

2,065 阅读5分钟

一、CSS优先级

1、CSS优先级介绍

浏览器根据优先级来决定给元素应用哪个样式,而优先级仅由选择器的匹配规则来决定。

下面列表中,选择器类型的优先度是递减的。

  • 内联样式(例如, style="...")
  • ID选择器(例如, #example)
  • 类选择器(例如, .example)、属性选择器(例如, [type="radio"])、伪类(例如, :hover)
  • 类型选择器(例如, h1)、伪元素(例如, ::before)
  • 继承的样式

2、CSS优先级计算

在这里插入图片描述

为了方便将优先度数值化,我们将内联样式的权重设置为1000,id选择器的权重设置为100,类选择器的权重设置为10,元素选择器的权重设置为1。

比较CSS的优先级就是计算权重:
id选择器出现的次数*100 + 类选择器出现的次数*10 + 元素选择器出现的次数*1
权重越大则优先度越高。

注意:
1、给元素添加的内联样式 (例如, style="font-weight:bold") 总会覆盖外部样式表的任何样式 ,因此可看作是具有最高的优先级。
2、当权值相等的情况下,后出现的样式将覆盖先出现的样式。
3、继承的样式优先度不如直接指定的样式。
4、以上数值化的权重值只是我们拟化的,不代表着多个低等级的选择器就能超过1个高等级的选择器。无论多少个低等级的选择器都不会超过一个高等级选择器的优先度。
5、类选择器、属性选择器、伪类选择器优先级是一样的.

3、基于类型的优先级

优先级是根据选择器的类型进行计算的。

举例:属性选择器尽管选择了一个ID但是在优先级计算中还是根据类型计算,属于属性选择器等级,因此即使选择的是相同的元素,但ID选择器有更高的优先级,所以#idtest设置的样式生效。

#idtest{
  color:red;
}
[id ="idtest"]{
  color:blue;
}

<div id="idtest">文字会是什么颜色的呢?</div>

在这里插入图片描述


4、not伪类不参与优先级计算

[:not]否定伪类在优先级计算中会忽略掉:not,按照:not里面的选择器进行计算优先度。其他伪类(如:hover)参与CSS优先级的计算,但是[:not]不参与计算。

div:not(#idtest){
  color:red;
}
div.classtest{
  color:blue;
}
<div class="classtest">文字会是什么颜色的呢?</div>

在这里插入图片描述


按理,伪类选择器和类选择器的优先级是一样的,后面的类选择器将覆盖前面的伪类选择器;但是:not伪类不参与计算,:not内部的选择器参与计算,:not内部的选择器为ID选择器,优先度高于类选择,所以最终显示为红色。

5、优先级计算无视DOM树中的距离

body h3{color:blue;}
html h3{color:red;}

<html>
    <body>
         <h3>文字会是什么颜色的呢?</h3>  
    </body>
</html>

在这里插入图片描述


body标签离h3标签更近,但是优先级计算无视DOM树的距离,body h3的优先级和html h3的优先级一样,html h3的样式覆盖了body h3的样式。

二、!important

1、!important介绍

当在一个样式声明中使用一个!important 规则时,此声明将覆盖任何其他声明。

使用 !important 是一个坏习惯,应该尽量避免,因为这破坏了样式表中的固有的级联规则 使得调试找bug变得更加困难了。当两条相互冲突的带有 !important 规则的声明被应用到相同的元素上时,拥有更大优先级的声明将会被采用。

注意:

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

推荐:

  • 更好地利用CSS级联属性。
  • 使用更具体的规则。在您选择的元素之前,增加一个或多个其他元素,使选择器变得更加具体,并获得更高的优先级。

2、什么情况下可以使用!important

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

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

2)、如下情况

#someElement p { color: blue; } 
p.awesome { color: red; }

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

3、如何覆盖!important

1)、只需再添加一条带 !important 的CSS规则,然后给这个给选择器更高的优先级(添加一个标签,ID或类);或是当选择器优先级一样的情况下,把它的位置放在原有声明的后面(同等优先级,后面的将覆盖前面的)。
2)、或干脆改写原来的规则,以避免使用 ! important 。