一个CSS选择器陷阱:你的浏览器是色盲吗?

标签:CSS

刚才在测试CSS选择器时发现一个奇怪的问题,连IE浏览器(我只测试了IE 6和IE 7)都计算错了,不知道大家能不能得出正确答案:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN" lang="zh-CN">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=gbk"/>
		<title>你的浏览器是色盲吗?</title>
		<style type="text/css">
			p.p#p {color: red;}
			div.d #p {color: blue;}
		</style>
	</head>
	<body>
		<div class="d">
			<p id="p" class="p">这是什么颜色?</p>
		</div>
	</body>
</html>
如果你的答案是红色的话,恭喜你,你和IE一样计算错了。

当然,这道题是很简单的,于是再看下一题:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN" lang="zh-CN">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=gbk"/>
        <title>你的浏览器是色盲吗?</title>
        <style type="text/css">
            #s {color: red;}
            .b div #p span.s {color: green;}
            body.b div#d .s {color: blue;}
        </style>
    </head>
    <body class="b">
        <div id="d" class="d">
            <p id="p" class="p">
                <span class="s" id="s">这是什么颜色?</span>
            </p>
        </div>
    </body>
</html>
如果你的答案是红色,那么你的CSS基础肯定没打好;如果你的答案是绿色,那么恭喜你,你又和IE一样计算错了。

下面就给出为何这样计算的原因吧。
众所周知,CSS的全称就是层叠样式表,也就是样式是可以层叠的,那么选择哪个样式自然是有计算方法的。然而计算样式是很复杂的,需要通过这几个方面来确定:
  1. 当一个样式被标记为!important时,它就是最重要的,其他非!important样式不可能去覆盖它。然而遗憾的是:IE 6不认识这个声明。
  2. 接着就是由谁声明的了:用户自定义的样式优先级最高(只有部分浏览器可以自定义样式),网站作者定义的样式次之,浏览器内置的样式(即缺省样式)最低。
  3. 如果上述优先级都相同,则要计算特异性了,它共有四个组成部分:a、b、c和d:
    1. a表示是否为内嵌样式(在元素的style属性里声明,或用JavaScript进行设置的),是则为1。特别注意:内部样式(同一个页面中用style元素声明的样式)和外部样式(用link元素引入的样式)的特异性相同,这点经常会被弄错。[/*]
    2. b表示id选择符(#)的数量。[/*]
    3. c表示属性选择符(包括类选择符)和伪类的数量。不过IE 6不支持属性选择符,很多伪类也不支持。[/*]
    4. d表示元素类型和伪元素的数量。[/*]
  4. 最后,如果特异性仍相同,则后声明的样式覆盖先声明的。

于是看第一题,id选择器都是1个,类选择器也都是1个,元素种类也都是1。因此特异性完全相同,下面的声明覆盖上面的声明。
再看第二题,id选择器都是1个,类选择器也都是1个,元素种类分别是1、2、2种。因此特异性方面,div.d #s被淘汰,剩下的由后声明的覆盖先声明的。

最后还有种特殊情况,就是一个元素在没有设置任何样式(除了浏览器默认样式)时,仍会从父元素继承部分样式。当然,父元素的样式计算仍符合上述规则。
于是再出一题,看看你和IE 6是不是又犯同样的错(IE 7居然对了):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN" lang="zh-CN">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=gbk"/>
		<title>你的浏览器是色盲吗?</title>
		<style type="text/css">
			a:hover {color: red;}
			.p a {color: blue;}
		</style>
	</head>
	<body>
		<p class="p"><a href="#"><span>鼠标移到这里会是什么颜色?</span></a></p>
	</body>
</html>
至于这题的答案和解释,仔细看看规则应该就知道了,实际上有没有span是无所谓的。
如果你觉得本文不够详细的话,还可以看看《CSS Specificity: Things You Should Know》这篇文章,里面有很多关于计算特异性的例子。

0条评论 你不来一发么↓

    想说点什么呢?