1、特殊性
为什么id的优先级要高于class?
这就涉及到了CSS选择器的特殊性,而这个特殊性是由选择器本身的组件确定。特殊性表述为4个部分,如0,0,0,0。
常用选择器的特殊性如下:

  • 各ID选择器,加0,1,0,0
  • class、属性选择、伪类,加0,0,1,0
  • 其他,加0,0,0,1
  • 每个内联声明的特殊性都为1,0,0,0
  • 结合符(+)和通配选择器(*)对特殊性没有贡献,通配选择器特殊性为0,0,0,0;结合符没有特殊性

特殊性的比较规则是从左至右按位比较。

例如:

  1. h1{color:red}??//特殊性为:0,0,0,1
  2. p h1{color:green;}? ? //特殊性为:0,0,0,2即两个0,0,0,1相加 (胜者)
  3. h2#div1{color:blue}? ?//特殊性为:0,1,0,1(胜者)
  4. h2{color:black}? ???//特殊性为:0,0,0,1

复制代码

而我们常说的ID的优先级高于class,是因为id的特殊值是0,1,0,0;而class则为0,0,1,0 ;0,1,0,0>0,0,1,0
内联样式优先级高于外联样式,也是同样的道理,所有的内联样式特殊性都为1,0,0,0高于外联样式的特殊性。

2、重要性
我第一次看到!important是在解决浏览器兼容性问题的时候,看别人hack是这么写的,就开心的拿去用,问题解决了,就觉得真是神奇。
当时根本不会去想最好避免使用hack,更不会去想为什么!important这么神奇,到今天才有那么点明白了。
!important其实是代表CSS重要性的符号,放置在结束分号之前,!important必须正确的放置,否则声明无效。标 志!important的声明并没有特殊的特殊性值,不过要将其与非重要声明分开考虑。如果一个非重要声明和一个重要声明冲突,重要声明将胜出。

3、继承
因为基于继承机制,样式不仅会应用到指定的元素,还会应用到他的后代元素。
例如:

  1. h1{color:green;}
  2. 你好Tom

复制代码

h1中的字会变绿色,其子元素em中的字也会变成绿色。
CSS中的有些属性是不具有继承机制的,大多数框模型属性(包括外边距、内边距、背景、边框)都不能继承。
继承的值没有特殊性,甚至连0特殊性都没有。0特殊性要比无特殊性要强。

例如:

  1. *{color:black;}
  2. h1{color:red;}
  3. 你好TOM

复制代码

这个例子中“你好”是红色的,而“TOM”会变成黑色,这是因为通配符的特殊性值是0,而继承的值没有特殊性,所以采用黑色。
我想这就是为什么前辈们说不加区别的使用通配符是不专业的原因,通配符的使用会使继承出现短路的现象。

4、层叠
当特殊性相同的两个规则同时应用到同一个元素时,就要用到层叠了。一般是按照顺序来选择的,例如:

  1. h1{color:red;}
  2. h1{color:blue;}

复制代码

h1将是蓝色的。

我总结了一下,CSS大概是这么运作的。
首先,按照重要性,即根据!important标志将样式分成重要声明和非重要声明两组。
然后,在组再根据特殊性值进行排序
最后,按照样式放置顺序进行取舍

具体CSS层叠规则有如下4条:

1、找出所有相关规则,这些规则都包含与一个给定元素匹配的选择器

2、按显示权重对某元素的所有声明进行排序。标志!important的规则权重高于没有标志!important的规则。

3、按特殊性对给定元素的所有声明排序。有较大特殊性值的元素权重高于较小特殊性值的。

4、按出现顺序对给定元素的所有声明排序。一个样式或声明,越后出现权重越高,如果有导入样式,导入样式在前,主样式在后。

如果出现非CSS样式,如html中的font属性,则认为,其特殊性为0,并出现在样式表的最前面。