CSS,全称层叠样式表,很多人只知道CSS是用来控制样式的,并没有真正深入理解“层叠”的含义
层叠,其实指的就是“样式的覆盖”,当样式的覆盖发生冲突时,以优先级高的为准。当“同一个元素”的“同一个样式属性”被运用上多个属性值时,就需要遵循一定的优先级规则。常见的样式覆盖发生冲突有以下五种情况:
- 引用方式冲突。
- 继承方式冲突。
- 指定样式冲突。
- 继承方式和指定样式冲突。
- !important。
1.引用方式冲突
众所周知CSS有以下三种引入方式,外部样式,内部样式,行内样式,CSS引用方式的不同,也会产生冲突。这三种方式的优先级如下:
行内样式>内部样式=外部样式
行内样式的优先级最高,内部样式与外部样式的优先级相同,当内部样式与外部样式同时存在时,则以最后引入的为准(后来居上原则)。
举例:
<!doctype html>
<html lang="CN">
<head>
<title></title>
<meta charset="utf-8">
<link href="index.css" rel="stylesheet" type="text/css">
<style type="text/css">
body{
font-size:14px;
font-family:"Microsoft Yahei";
}
div{color:red;}
</style>
</head>
<body>
<div style="color:blue;">hello world</div>
</body>
</html>
在这个例子中,我们定义外部样式为color:green,内部样式为color:red,行内样式为:color:blue,浏览器预览效果如下图所示:
可见行内样式的优先级最高,如果去掉行内样式,则显示为red,因为内部样式比外部样式后引入。
2.继承方式冲突
如果由于继承方式引起的冲突,则“最近的祖先元素”获胜。
举例:
<!doctype html>
<html lang="CN">
<head>
<title></title>
<meta charset="utf-8">
<style type="text/css">
body{
font-size:14px;
font-family:"Microsoft Yahei";
}
#grandfather{color:yellow;}
#father{color:blue;}
</style>
</head>
<body>
<div id="grandfather">
<div id="father">
<div id="son">hello world</div>
</div>
</div>
</body>
</html>
浏览器预览效果如下:
离“son”最近的祖先元素是“father”,所以显示color:blue,如果father元素没有定义color属性,则最近的祖先元素为grandfather元素。
3.指定样式冲突
所谓的指定样式,指的是指定“
当前元素”的样式,当直接指定的样式发生冲突时,样式权值高的获胜。
CSS中,各选择器权值如下表:
选择器
| 权值 |
---|---|
通配符
|
0
|
伪元素
|
1
|
元素选择器
|
1
|
class选择器
|
10
|
伪类
|
10
|
属性选择器
|
10
|
id选择器
|
100
|
行内样式
|
1000
|
常用的选择器优先级如下:
行内样式>id选择器>class选择器>元素选择器
举例:
<!doctype html>
<html lang="CN">
<head>
<title></title>
<meta charset="utf-8">
<style type="text/css">
body{
font-size:14px;
font-family:"Microsoft Yahei";
}
#abc{color:red;}
.abc{color:blue;}
div{color:yellow;}
</style>
</head>
<body>
<div id="abc" class="abc">hello world</div>
</body>
</html>
浏览器预览效果如图:
可见id选择器权重最高,因此最终为color:red,这里要注意一点,我们不应只从样式顺序来判断。因为只有选择器权重相同时,才遵循“后来者居上”原则。
特殊举例:
<!doctype html>
<html lang="CN">
<head>
<title></title>
<meta charset="utf-8">
<style type="text/css">
body{
font-size:14px;
font-family:"Microsoft Yahei";
}
#outer p{
/*权值=100+1=101*/
color:red;
}
#outer .inner{
/*权值=100+10=110*/
color:green;
}
#outer p strong{
/*权值=100+1+1=102*/
color:blue;
}
#outer p span strong{
/*权值=100+1+1+1=103*/
color:purple;
}
</style>
</head>
<body>
<div id="outer">
<p class="inner">
<span><strong>hello world</strong></span>
</div>
</div>
</body>
</html>
浏览器预览效果如图:
发现<strong>标签的颜色为purple,虽然#outer .inner{}的权值最高,但是没有按最高权值显示颜色,这是为什么呢?那是因为所谓的制定样式冲突,指的是 当前元素的样式发生冲突,在这个例子中,我们所针对的当前元素是strong,而“#outer .inner{}”针对的元素是“p(strong的祖先元素)”。
准确来说,如果当前元素为“strong”,则“#outer .inner{}”和“#outer p”都属于继承样式,在继承样式中,我们是不能用选择器权重这一套来计算的。
由此我们可以知道,在CSS中,选择器权重的计算只能针对指定样式(当前元素),并不能用于继承样式。由此,我们可以引出下面的一种样式冲突。
4.继承样式与指定样式冲突
当继承样式与指定样式发生冲突时,指定样式获胜。
举例:
<!doctype html>
<html lang="CN">
<head>
<title></title>
<meta charset="utf-8">
<style type="text/css">
body{
color:red;
}
#outer{
color:green;
}
#outer .inner{
color:blue
}
span{
color:purple;
}
strong{
color:black;
}
</style>
</head>
<body>
<div id="outer">
<p class="inner">
<span><strong>hello world</strong></span>
</div>
</div>
</body>
</html>
浏览器预览效果如图:
可见由于css的继承性,strong元素分别从body,div,p这三个元素继承了color属性,但是这些都是继承样式,最后,由于“strong{color:black}”这句指定了strong元素的color属性(指定样式),因此最终strong元素color显示black。我们先判断指定样式,再判断继承样式。
5.!important
在css中,我们可以使用!important来改变样式的优先级,如果一个样式用!important来声明,则这个样式会覆盖css中任何的其他样式声明。也就是说,如果你一定要用某个样式,为了不让他被覆盖,则可以使用!important来实现。换句话说,如果你想要覆盖其他所有样式,可以使用!important来实现。
举例:
<!doctype html>
<html lang="CN">
<head>
<title></title>
<meta charset="utf-8">
<style type="text/css">
body{
font-size:14px;
font-family:"Microsoft Yahei";
}
#outer p strong{
/*权值=100+1+1=102*/
color:red;
}
#outer .inner strong{
/*权值=100+10+1=111*/
color:green;
}
#outer p strong{
/*权值=100+1+1=102*/
color:blue !important;
}
#outer p span strong{
/*权值=100+1+1+1=103*/
color:purple;
}
</style>
</head>
<body>
<div id="outer">
<p class="inner">
<span><strong>hello world</strong></span>
</div>
</div>
</body>
</html>
浏览器显示效果如图:
按理说#outer .inner strong{color:green;}权值最高(111),应该显示绿色,可是浏览器显示的却是blue,这就是因为“#outer p strong”中用了!important,所以最终显示为蓝色。
在CSS中,!important常见有两种使用情况。
(1)情况一
#someId p{color:red;}
p{color:green;}
在外层有#someId的情况下,怎样才能让p变为green呢,这时候就要!important出马了,如果不使用!important,第一条的优先级永远比第二条高。
(2)情况二
试想一下如下情况,你或者你的同事写了一些效果很差的行内样式(行内样式的优先级最高),假如你要在内部样式或者外部样式表中修改这个样式,你就应该想到使用!important来覆盖这些糟糕的样式。在举一个活生生的例子,有人用jQuery插件写了糟糕的行内样式,而你需要在CSS文件中修改这些样式。
试想一下如下情况,你或者你的同事写了一些效果很差的行内样式(行内样式的优先级最高),假如你要在内部样式或者外部样式表中修改这个样式,你就应该想到使用!important来覆盖这些糟糕的样式。在举一个活生生的例子,有人用jQuery插件写了糟糕的行内样式,而你需要在CSS文件中修改这些样式。
那么如何覆盖!important样式呢,共有以下两种方法:
(1)
使用相同的选择器,再写一条!important的CSS语句。记住这句
一定要放在前面一条的后面,因为后来者居上原则。
(2)
使用更高优先级的选择器,再添加一条!important语句。这句就不一定要放在后面了,因为优先级更高。