CSS结构和层叠
继承是从一个元素向其后代元素传递属性值所采取的机制。确定应当向一个元素应用那些值时,用户代理不仅要考虑继承,还要考虑声明的的特殊性,另外需要考虑声明的来源。这个过程成为层叠。接下来我们就了解下css的特殊性和重叠等。
像css权威指南里说的一样,不管怎样,无论为看上去多抽象、多难懂,都要努力!你的努力不会白费。
特殊性
在CSS中针对某个元素的多个相同的规则,浏览器会计算其特殊性。如果一个元素有多个冲突的规则,具有最高特殊性的声明会胜出。
选择器的特殊性由选择器本身的组件确定。特殊性值表述为4个部分,如:0,0,0,0,具体规则如下:
- 对于内联声明(style)的特殊性为1,0,0,0;
- 对于选择器中给定的各个ID属性值,加0,1,0,0;
- 对于选择器中给定的各个类属性值,属性选择或伪类,加0,0,1,0;
- 对于选择器中给定的各个元素和伪元素,加0,0,0,1;
- 通配符(*)的特殊性为0,0,0,0;
- 结合符和继承没有特殊性;
h1 {color: red} /*0,0,0,1*/
p em{color: purple} /*0,0,0,2*/
.grape{color: purple} /*0,0,1,0*/
*.bright{color: yellow} /*0,0,1,0*/
p.bright em.dark{color: maroon} /*0,0,2,2*/
#id216{color: blue} /*0,1,0,0*/
div#sidebar *[href]{color: silver} /*0,1,1,1*/
具体权重可见下表:
Selectors 选择符 | Syntax Samples 语法 | ensample 示例 | Specificity 特性 |
---|---|---|---|
通配选择符(Universal Selector) | * | *.div { width:560px;} | 0,0,0,0 |
类型选择符(Type Selectors) | E1 | td { font-size:12px;} | 0,0,0,1 |
伪类选择符(Pseudo-classes Selectors) | E1:link | a:link { font-size:12px;} | 0,0,1,0 |
属性选择符(Attribute Selectors) | E1[attr] | h[title] {color:blue;} | 0,0,1,0 |
ID选择符(ID Selectors) | #sID | #sj{ font-size:12px;} | 0,1,0,0 |
类选择符(Class Selectors) | E1.className | .sjweb{color:blue;} | 0,0,1,0 |
子对象选择符(Child Selectors) | E1 > E2 | body > p {color:blue;} | E1+E2 |
相邻选择符(Adjacent Sibling Selectors) | E1 + E2 | div + p {color:blue;} | E1+E2 |
选择符分组(Grouping) | E1,E2,E3 | .td1,a,body {color:blue;} | E1 E2 E3 |
包含选择符(Descendant Selectors) | E1 E2 | table td {color:blue;} | E1+E2 |
重要性
有时某个声明可能非常重要,超过了所有其他声明。CSS2.1称之为重要声明,并允许在这些声明的结束分号之前插入!important标志。
h1 {font-style: italic !important;
color: gray !important;
background: red !important;
}
标志为!important的声明并没有特殊的特殊性值,,不过要与非重要声明分开考虑。实际上所有!important的声明会分组在一起,重要声明的特殊性冲突会在重要声明内部解决,而不会与非重要声明相混。类似的所有非重要声明也归为一组,使用特殊性来解决冲突;
重要规则会胜出
h1 {font-style: italic !important;
color: gray !important;
background: red !important;
}
.title {
color: black;
background: silver;
}
* {
·background: black !important;
}
注意:
- 非0的数值越靠前,特殊性越高,同一位置的非0的数值,值越大,特殊性越高
- 继承没有特殊性,甚至连0特殊性都没有,而通配符有特殊性,所以通配符的特殊性大于继承
- 内联样式style和!important使用同一属性时,!important 胜出
继承
基于继承机制,样式不仅应用到指定的元素,还会应用到它的后代元素,并且一直延续,一直到没有元素可以继承为止。
继承是CSS中最基本的内容质疑,除非有必要的理由,否则一般不会特别考虑,正所谓”熟视无睹“。不过,以下几点需要注意:
- 注意有些属性不能被继承,比如说border,如果可以继承,那么页面显示会很乱。
- 继承的值无特殊性
<p>结构和层叠<em>继承与通配符的重要关系</em></p>
p {color: gray;}
* {color: red}
结果显示em不会继承p元素的颜色,而是显示red,0特殊性>无特殊性。通配选择器的特殊性就是0,所以通配符选择器>继承。
层叠
如果特殊性相等的两个规则同时应用到元素上,这个元素该如何显示呢?
层叠的规则
- 找出所有相关的规则,这些规则都包含一个给定元素匹配的选择器。
- 按照重要性对规则分组排序。标志!important规则的权重高于没有!important标志的规则。按来源对应用到给定元素的所有声明排序。共有3种来源:创作人员,读者,用户代理。正常情况下,创作人员的样式要胜于读者的样式表有!important标志的读者样式要强于所有其他样式,这包括有!important标志的创作人员样式。创作人员样式和读者样式都比用户代理的默认样式要强。
- 按特殊性对应用到给定元素的所有声明排序。有较高特殊性的元素权重重要大于较低特殊性的元素。
- 按出现顺序对应用到给定元素的所有声明排序。一个声明在样式表或文档中越后出现,它的权重就越大。如果样式表中有导入样式表的话,一般认为出现在导入样式表中的声明在前,主样式表中的所有声明在后。
按权重和来源排序
若两个样式规则应用到同一个元素,而且其中一个规则有!important标志,这个重要规则将胜出。
在声明权重方面要考虑5级,权重由大到小的顺序依次为:
- 读者的重要声明
- 创作人员的重要声明
- 创作人员的正常声明
- 读者的正常声明
- 用户代理声明
创作人员通常只需要考虑前四种权重级别,因为任何声明都会胜过用户代理样式。
按特殊性排序
若向一个元素应用多个彼此冲突的声明,而且它们的权重相同,则要按特殊性排序,最特殊的声明最优先。
p#bright{color:silver;}
p{color:black;}
<p id="bright">well, hello there!</p>
根据以上的规则,段落的颜色是银色的,因为p#bright的特殊性(0,1,0,1)大于 p的特殊性(0,0,0,1),尽管后一条在样式表中较后出现。
按顺序排序
若两个规则的权重,来源和特殊性完全相同,那么在样式表中后出现的一个会胜出。
特别地,认为元素style属性中指定我样式位于文档样式表的最后,即放在所有其他规则的后面。
正是由于这种按顺序排序,所以才有了通常推荐的链接样式顺序:link-visited-focus-hover-active(LVFHA)。
:link {color: blue;}
:visited {color: purple;}
:focus {color: green;}
:hover {color: red;}
:active {color: orange;}
非CSS表现提示
文档有可能包含非CSS的表现提示,例如font元素。非CSS提示被处理为特殊性为0,并出现在创作人员样式表的最前面。只要有创作人员或读者样式,这种表现提示就会被覆盖,但用户代理的样式不能将其覆盖。