冲突
CSS 本质上就是声明规则,即在各种条件下,我们希望产生的特定效果。 在某些时候,在做一个项目过程中你会发现一些应该产生效果的样式没有生效。通常的原因是你创建了两个应用于同一个元素的规则, 且两个规则发生了冲突。要想实现最终的效果,就需要理解CSS里的层叠。
为了演示, 我构建了一个简单的网页头部。上面是网站标题,下面是一排导航按钮,其中前两个背景为青蓝色,最后一个时橘黄色,用来表示其特殊性。
对于button
元素我们声明了两个规则, 且这两个规则中包含冲突的声明:
两个规则尝试给按钮设置不同的背景颜色,哪一个会生效呢? 浏览器为了解决这个问题会遵循一系列规则,因此最终的效果是可以预测的。
层叠
下面来分享层叠的规则。当声明冲突时,层叠会依据三种条件解决冲突:
样式表的来源
: 样式是从哪里来的,包括你的样式和浏览器默认样式。优先级
: 哪些选择器比另一些选择器更重要。源码顺序
: 样式在样式表里的声明顺序。
样式表的来源
你添加到网页里的样式表并不是浏览器唯一使用的样式表,还有其他类型或来源的样式表。这些来源包括:
用户代理样式(user agent stylesheet)
:即浏览器默认样式表。 这些是默认情况下您的浏览器应用于 HTML 元素的样式用户样式
: 作为浏览器的用户,可以使用自定义样式表定制使用体验, 例如允许用户为网页编写自定义 CSS 的浏览器扩展程序作者样式
: 作为网页的作者,您自行编写的样式。这是最常见的样式表。
样式表的来源规则有一个例外: 标记为!important
的声明。 如下所示,在声明的后面加上!important
, 该声明就会被标记为重要的声明:
标记了!important
的声明会被当做更高优先级的来源,因此总体的优先级按照由低到高排列如下所示:
假设层叠的顺序相同,则使用那个规则取决于优先级
优先级
如果无法用来源解决冲突声明,浏览器会尝试检查它们的优先级。 浏览器通过优先级来判断哪些属性值与一个元素最为相关,从而在该元素上应用这些属性值。
浏览器将优先级分为两部分:HTML的行内样式
和选择器的优先级
。
行内样式
行内样式使用style
属性给当前元素设置样式,它会覆盖任何来自样式表或者<style>
标签的样式
选择器优先级
优先级的第二部分由选择器决定。 每条选择器都会获得一个评分x-y-z
,评分分越高的选择器优先级越高。
x
: 代表id
选择器数量,可以理解为百分位
y
: 代表类、属性、伪类选择器数量, 可以理解为十分位
z
: 代表元素选择器和伪元素选择器数量, 可以理解为个位
最终评分为: 100x + 10y + z
为便于参考, 以下选择器评分为 1-4-1
即141
下面这张图详细列举了各种选择器的评分, 其中还有4个数和5个数的标记:
inline-style
:1-0-0-0
!important
:1-0-0-0-0
源码顺序
层叠的第三步,也是最后一步,是源码顺序。如果两个声明的来源和优先级相同,其中一个声明在样式表中出现较晚,或者位于页面较晚引入的样式表中,则该声明胜出。
继承
CSS继承是一个重要的概念,它描述了当一个CSS属性没有在元素上显式设置时,该属性如何从其父元素继承。这意味着,如果一个元素的某个属性没有被指定,那么它将自动从其父元素那里继承该属性的值。
inherit
可以使用 inherit
关键字使任何属性继承于其父元素的值。
initial
有时,你需要撤销作用于某个元素的样式。这可以用initial
关键字来实现。每一个CSS属性都有初始(默认)值。如果将initial
值赋给某个属性,那么就会有效地将其重置为默认值,这种操作相当于硬复位了该值