层叠,特殊性和继承
层叠
在各样式声明冲突时,层叠性考虑这些去解析:
- 样式表来源
- 选择器的特殊性
- 源顺序
样式表来源
UA样式
开发人员添加的样式表并不是唯一被浏览器应用的样式表,此外,用户代理(User Agent)也有自己的一套规则,它们和author styles一并用于样式渲染。有些浏览器还让用户自定义样式,暂不考虑。
UA的样式因浏览器不同而不同,但大体保持如下:h1到h6以及p具有上下外边距,列表(ol和ul)具有左内边距,上下外边距,而链接颜色和字体大小也被设定。列表的list-style-type设置为disc显示为无序列表的左侧圆点。
UA样式可被author style重写,因为后者优先级更高。如果在html中引入多个样式表,它们都具有author style的优先级别。
important声明
声明的分号前加一个!important
会以更高的优先级源来处理。所以author important>author>user agent。
每个元素的property都被独立处理,当在p标签上设置粗体时,并不会影响p标签的UA定义的上下外边距样式。
特殊性
如果矛盾声明无法通过源来解决,那么就需要考虑声明的特殊性。浏览器用两部分来评估特殊性,一方面是HTML应用的行内样式,一方面是用选择器应用的样式。
行内样式
行内样式直接应用到定位元素,因为他们不存在选择器一说。而应用的行内样式会覆盖style标签或者外部样式表定义的样式。
为了在外部样式表或者style标签中重写行内样式声明,可以添加!important
声明使之成为具有更高优先级的源。如果行内样式添加了!important
,那么它的声明永远不会被覆盖,最好在样式表中使用!important
。
选择器特殊性
简言之,选择器的特殊性这样理解:
- 如果一个选择器有更多的ID选择器,则优先级更高
- 如果ID选择器相同,则具有更多的类选择器的优先级更高
- 如果类选择器也相同,则看元素选择器
伪类选择器(:hover)和属性选择器([type=”input”])和类选择器特殊性等同,而通用选择器(*)和连接符(> + ~)对特殊性没有影响。
如果有时候你写的规则无效,很有可能是别的具有更高特殊性的规则重写了它。许多程序员滥用id选择器却不知道id选择器具有更高的特殊性,使得后期重写其样式变得困难,因为你必须使用另一个id选择器。
特殊性记法
普遍的记录特殊性的方法就是用逗号分割的3个数字,依次代表id选择器,类选择器和元素选择器的数量。1,0,0的特殊性要高于0,10,1,因为id选择器具有更高优先级。
有时,人们也使用4个数字的记法,其中第一个数字代表行内样式,0代表没有行内样式,1代表有行内样式,存在行内样式时,无论后面数字是多少,都会解析为行内样式。
特殊性注意事项
尽可能降低使用的选择器的特殊性,便于后期维护。
理解源顺序
如果源和特殊性都相同,就要看源顺序,出现在同一样式表中靠后的规则被应用,出现在同一页面后引入的样式表样式被应用。
1 | a:link { |
同样的特殊性,定义在后面的样式被应用,当我们hover的时候,样式要覆盖掉link状态的样式和visited状态的样式,而active状态下要覆盖掉hover状态的样式。可通过LoVe/HAte来助记。
层叠值(cascaded value)
浏览器遵循这三个步骤——源,特殊性,源顺序为页面每个元素的每个属性做解析,并最终得到一个层叠值做渲染。每个属性只可能有一个层叠值,如果一个属性从始至终没有被任何源指定,那么它没有层叠值。比如p元素可能没有内边距或者边框。
两个经验法则
- 不要使用ID选择器
- 不要使用!important
不过也有例外的情况,只是不要将它们作为赢得特异性战争的武器而已。
继承
如果属性没有层叠值,那么它可能会从祖先元素继承。如在body上定义font-family,那么所有的后代元素都会自动继承这个规则。
并非所有属性都会被继承,这些被继承的属性多是你期望要被继承的属性,一般和文字相关:color , font , font-family , font-size , font-weight , font-variant , font-style , line-height , letter-spacing , text-align , text-indent , text-transform , white-space , word-spacing等。
还有列表相关的list-style , list-style
-type , list-style-position , list-style-image等。表格边框属性border-collapse , border-spacing也被继承。
特殊值
有两个特殊值可被用于设置属性来修改你的层叠:inherit
和initial
。