首页>前端教程>CSS教程

CSS第三课:选择器的继承、叠加、冲突优先级详解

CSS的全名叫“层叠样式表”,“层叠”是非常关键的一个词,代表了不同来源的样式在最终的效果上呈现继承、叠加、冲突覆盖等。

一、CSS的五种来源

1、浏览器默认样式

2、浏览器用户自定义样式

3、<link>外部样式表

4、<style>内部样式表

5、<标签  style="">行间样式表

如果对css在网页中的应用不清楚的同学,可以先看这篇文章:CSS第二课:如何应用CSS到网页中?

前面两种关于浏览器的样式,前端程序员一般不会涉猎,一个是不同厂商为浏览器内置的样式,比如<h1>文字加大加粗,默认颜色黑色,字体宋体,这就是浏览器的默认样式,不同厂商浏览器的默认样式会有细微差异,这就是为什么我们需要做“css reset”样式的原因。

第二种浏览器用户自定义的样式,比如用户视力不好,可以在设置菜单里面把字体加大,或者改变颜色等,这是网页终端用户的个人行为。他们的设置会覆盖浏览器的默认样式。

浏览器用户自定义样式.png

另外三种样式的层叠是我们需要重点讲解的内容。

二、CSS的继承

如果你能继承你父辈的财产,那么html标签中,后代元素也能继承父辈元素的样式

如果对DOM节点树有概念,那么应该很好理解。

DOM节点树.jpg

我们的html文档的所有标签就是一个一个节点,整个html文档看起来像一颗树一样。

body是正文所有标签的父节点。

所以你为body所做的样式,整个文档的其他标签都会继承。

比如:

body{
	font:16px/1 "microsoft YaHei";
	background-color:#eee;
	color:#333;
	}

body里面的p、h1-h6、ul、span、a等都会继承该样式,但是h标签有自己的文字大小,a标签有自己的颜色等不能被覆盖。

比如:

<p>段落文字<span>span内容</span></p>

样式:

p{
	font-size:1.05em;}

则p里面的span会继承p定义的文字大小为1.05em的样式。

三、CSS的叠加

如果学了数学里面集合的概念,这个也好理解,所以谁说数学外语不重要的!我们任何稍微高级点的知识都是以语数外为基础的。

比如集合A包含有{a,b,c},集合B包含有{d,e},则取两个集合的并集则是{a,b,c,d,e}。

如果一个元素用了几个样式,则该元素会使用这几个样式的最大集合。

比如:

.f16{
    font-size:16px;
}
.l180{
    line-height:180%;/*行高为180%*/
}
.p20{
    padding:20px;/*内边距为20px*/
}
<p class="f16 l180 p20">段落文本</p>

则该段落会叠加使用三个class所定义的样式。

四、CSS的冲突

比如:

a{
	color:#F60;
	text-decoration:none;}
a:hover{
	color:#09C;
	text-decoration:underline;}
#nav a{
	color:#093;}
#nav a:hover{
	color:#FC3;}

#nav a重新设置了color颜色,则和基础样式a的color冲突,#nav a:hover的color样式也和a:hover的color冲突。

冲突就是为一个元素设置了多个样式,样式中的属性是一样的,但是属性值不一样,导致了冲突。

#nav a是为#nav下面的a标签设置样式,但是这个a标签也会继承来自于基础样式那里设置的a样式。所以冲突需要解决的问题是选择器优先级的问题,谁的优先级更大,则使用谁定义的样式。

#nav a 的优先级当然比a的大,所以最终执行的样式是冲突和继承后的结果:

#nav a{
	color:#093;/*冲突后执行该color定义的值。*/
	text-decoration:none;/*继承自a的基础样式*/
}
#nav a:hover{
	color:#FC3;/*冲突后执行该color定义的值。*/
	text-decoration:underline;/*继承自a:hover的基础样式*/
}

五、CSS选择器的优先级

在学习优先级之前,先了解一个概念——特指度(specificity)[ˌspesɪˈfɪsəti],通过一个公式计算出该选择器的特指度,特指度越大,则该选择器越重要,优先级越高。

一个id为100,一个class为10,一个标签为1,举例如下:

CSS选择器特指度计算结果
p1
p span2
.box10
.box p11
a.current11
#main
100
#main .box110
#main .box a
111
#nav ul li.last a
113

注意:有!important的最重要,高于一切,通配符“*”最低,低于一切选择器。

比如:

p{
	color:#f00 !important;/*表示最重要的,放在分号“;”的前面*/}
#color{
	color:#ff0;}
<p id="color">段落文本</p>

则段落的文本颜色也会使用f00的红色而不是ff0的黄色。

1、样式表的优先级

在选择器特指度一样的情况下,外部样式表在内部样式表前面,内部样式表优先。

<link href="css.css" rel="stylesheet" type="text/css">
<style type="text/css">
p{
	color:#f00;}
</style>

反之,外部样式表在内部样式表之后,则外部样式表优先。

<style type="text/css">
p{
	color:#f00;}
</style>
<link href="css.css" rel="stylesheet" type="text/css">

如果,元素有行间样式表,则行间样式表优先,据说行间样式表的特指度为1000,谁知道呢,反正最大就是了。慎用!慎用!

<p id="color" style="color:#F60;">段落文本</p>

很多时间看到别人的网页上有这种行间样式表,其实大部分都是用javascript产生的。比如:

var p=document.getElementsByTagName("p")[0];
p.style.color="#f90";

这样的脚本就会把样式直接放在标签里面成为行间样式表。

最好的方式还是用className添加样式。

var p=document.getElementsByTagName("p")[0];
p.className+=" class名称";

结论:行间样式表优先级最大。相同特指度的样式,外部样式表和内部样式表根据先后顺序,后添加的优先级大。

2、在同一个样式表里,相同特指度的优先级

.color1{
    color:#f00;
}
.color2{
    color:#ff0;
}
<p class="color1 color2">文本</p>

如果一个对象使用了两个特指度一样的样式, 则根据程序默认从上往下执行的原理,后定义的样式会覆盖先定义的样式。这与p调用class样式的先后顺序没有关系。

比如:

<p class="color2 color1">文本</p>

结果是一样的。

3、特指度不同的时候,则根据计算得出优先级。

body{
    font-size:14px;
}
p{
    font-size:16px;
}
.content p{
    font-size:18px;
}
#box .content p{
    font-size:20px;
}

后面的级别越来越大,就会逐渐覆盖body、p等定义的样式。p比body后定义,也会覆盖body的样式。

最后我们可以得出如下结论:

1、行间样式表优先级最大,建议不要使用,难于覆盖。

2、尽量使用外部样式表,如果有内部样式表,注意和外部样式表的先后顺序。

3、先用“css reset”清除浏览器之间的默认样式。让一切从“零”开始。

4、先用标签选择器设置整个网站的基础样式,比如body、p、a、img、li等,级别低,后面也好覆盖。

5、class样式可以合理的组合,不同的组合可以叠加出不同的效果。

6、复合选择器的路径尽量短,id选择器具有唯一性,用id的时候,只有一个id就行,比如#nav li,就不要用#main #nav ul li了。

7、学习CSS3新增的选择器,有利于减少class和id的使用。

8、在学习中实践,在实践中思考,思考后再学习,如此循环。

点赞


10
保存到:

相关文章

Top