浏览器根据层叠和继承规则确定显示一个元素时各种样式属性采用的值。
样式如何层叠
浏览器要显示元素时求索一个css属性值的次序为:
- 元素内嵌样式(用元素的全局属性style定义的样式)
- 文档内嵌样式(定义在style元素中的样式)
- 外部样式(用link元素导入的样式)
- 用户样式(用户定义的样式)
- 浏览器样式(浏览器应用的默认样式)
-
注:此处需要解释一下用户样式
- 大多数浏览器支持用户自定义自己的样式表。这类样式表中包含的样式称为用户样式。
设用户需要显示一个a元素。浏览器需要知道的一件事情是其文字应该显示何种颜色。为了解决这个问题,它需要为css属性color找到一个值。首先它会查看所要呈现的那个元素是否具有一条设定了color值的元素内嵌样式,比如下面这种:
<a style="color: red" href="http://www.baidu.com">百度</a>
如果不存在元素内嵌样式,那么接下来浏览器会看看是否有一个style元素包含着作用于那个元素的样式,比如下面这种:
<style type="text/css">
a{
color: red;
}
</style>
如果不存在这样的style元素,那么接下来浏览器会查看link元素载入的样式表,依次类推。
补充:元素内嵌样式,文档内嵌样式和外部样式表合称为作者样式。
用重要样式调整层叠次序
把样式属性值标记为重要(important),可以改变正常的层叠次序,例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>css的层叠</title>
<style>
a {
color: black !important;
}
</style>
</head>
<body>
<a style="color: red" href="#">test</a>
<hr>
<a href="#">test2</a>
</body>
</html>
运行结果为:
在样式声明后面附上!important即可将对应属性值标记为重要。不管这种样式属性定义在什么地方,浏览器都会给予优先考虑。
提示:能凌驾于作者定义的重要属性值之上的只有用户样式表中定义的重要属性值。对于普通属性,作者样式中的值由于用户样式中的值,而对于重要属性,情况正好相反。
根据具体程度和定义次序解决同级样式冲突
如果有两个定义于同一层次的样式都能应用于同一个元素,而且它们都含着浏览器要查看的CSS属性值,这时就需要另加砝码助天平上持平的双方一决高下。为了判断选用哪个值,浏览器会评估两条样式的具体程度,然后选中较为特殊的那条。样式的具体程度通过统计三类特征得出:
- 样式选择器中的id值的数目
- 选择其中其他属性的伪类的数目
- 选择器中元素名和伪元素的数目
在评定具体程度时要按a-b-c的形式(其中每一个字母一次代表上述三类特征的统计结果)如果对其某个样式算出的a值最大,那么它就是具体程度高的那个。只有a值相等时,浏览器才会比较b值,此时b值较大的样式具体程度更高。只有a值和b值分别相的时候,浏览器才会考虑c值。也就是说,1-0-0比0-5-5具体程度更高。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>css的具体程度</title>
<style>
a {
color: black;
}
a.myclass {
color: white;
background: grey;
}
</style>
</head>
<body>
<a href="#">test</a>
<hr>
<a class="myclass" href="#">test2</a>
</body>
</html>
本例中a.myclass这个选择器中有一个class属性,于是该样式的值为0-1-0(0个id值+1个其他属性+0个元素名)。另一条样式具体程度值为0-0-0,因此浏览器在呈现被归入myclass类的a元素时将使用a.myclass样式设定的color属性值。对于其他a元素,使用的则是另一条样式中设定的值。
运行结果如下:
如果同一属性出现在具体程度相当的几条样式中,那么浏览器会根据其位置的先后顺序选择所用的值,规则是后来居上。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>css定义次序</title>
<style>
a.myclass1 {
color: black;
}
a.myclass2 {
color: white;
background: grey;
}
</style>
</head>
<body>
<a href="#">test</a>
<hr>
<a class="myclass1 myclass2" href="#">test2</a>
</body>
</html>
运行结果如下:
颠倒样式定义的次序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>css定义次序</title>
<style>
a.myclass2 {
color: white;
background: grey;
}
a.myclass1 {
color: black;
}
</style>
</head>
<body>
<a href="#">test</a>
<hr>
<a class="myclass1 myclass2" href="#">test2</a>
</body>
</html>
运行结果如下:
不出所料color属性选择的是black这个值。
根据样式的具体程度和定义次序确定选用的样式,应把各个属性分开考虑。上述的几个例子,还定义了背景颜色。因为并非两个样式都有,所以不会发生冲突,也就没有必要查找其他值了。
继承
如果在浏览器直接相关的样式中找不到某个属性的值,就会求助于继承机制,使用父元素的这个样式属性值。例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>css继承1</title>
<style>
p {
color: white;
background: grey;
border: medium solid black;
}
</style>
</head>
<body>
<p>I like <span>HTML5</span> and CSS3</p>
</body>
</html>
运行结果为:
这个例子中没有针对span元素的样式设定color属性值,但浏览器显示该元素文字内容时却使用了前景色white。这个值系由父元素p继承而来。
但是并非所有的CSS属性都可继承。这方面有条经验可供参考:与元素外观(文字颜色,字体等)相关的样式会被继承;与元素在页面上的布局相关的样式不会被继承。在样式中使用inherit这个特别设定的值,可以强行实施继承,明确指示浏览器在该属性上使用父元素样式中的值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>css继承2</title>
<style>
p {
color: white;
background: grey;
border: medium solid black;
}
span {
border: inherit;
}
</style>
</head>
<body>
<p>I like <span>HTML5</span> and CSS3</p>
</body>
</html>
此例中,定义了一条用于span元素的样式,其border属性继承自父元素。