#CSS 选择器优先级的溢出 文章主要是根据《CSS权威指南》来对自己的一些不牢靠的知识进行记录巩固。 在选择器上,主要是一些特殊性和层叠顺序规则需要熟悉。 ##选择器的特殊性 选择器的特殊性由选择器本身的组件确定。 特殊性值表述为4个部分,如:0,0,0,0。一个选择器的具体特殊性如下确定:

  • ID属性值,加 0, 1, 0, 0。
  • 类属性值、属性选择或伪类,加 0, 0, 1, 0。
  • 元素和伪元素, 加 0, 0, 0, 1。
  • 结合符和通配符对特殊性没有任何贡献(即便无贡献,但和继承值还有浏览器默认样式相比,优先级还是结合符或通配符高)。
  • 一般第一个0是为内联样式保留的。

##层叠规则 按以下步骤顺序确定层叠规则:

  1. 找出匹配元素的规则
  2. 按显示权重对匹配元素所有声明排序,!important规则权重高于没有!important的规则;
  3. 按来源对声明排序,包括3种来源:创作人员、读者和用户代理。创作人员样式胜过读者样式。 有!important标识的读者样式要强于所有其他样式,这包括有!important标识的创作人员样式。 创作人员样式和读者样式都比用户代理的默认样式要强。
  4. 按特殊性对声明排序,较高特殊性胜出。
  5. 按顺序对声明排序,排在后的生出。

##一个坑 先来个例子: .test p span{color:red}; 特殊行为: 0, 1, 2, 0。 浏览器通过位来实现选择器的特殊性,这样就只需1个数字就可以表示了。 假设浏览器用1个数字按位表示特殊性,那么每一类别的特殊性肯定都是有上限的,正常情况下应该不会太大,这可以通过下面的代码来证明: ###基本思路 给一个id为test的div元素添加样式规则,同时给这个元素添加一定数量的class, 再将这些class结合给出另一个规则,如果到达一定数量的class规则覆盖了id规则,那么就证实了猜想。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>Selector Demo</title>
		<style>
			#test {
				color: red;
			}
		</style>
	</head>
	<body>
		<div id="test">
			这是一个div,id为test
		</div>
		类添加次数:
		<input type="text" id="count" />
		<input type="button" id="add" value="添加" />
		<script>
			document.getElementById('add').onclick = function() {
				var t = document.getElementById('test');
				var count = Number(document.getElementById('count').value);
				var cls = '';
				var css = '';
				//加它个count个类,同时拼接CSS字符串
				for (var i = 0; i < count; ++i) {
					cls += 't' + i + ' ';
					css += '.t' + i;
				}
				css += '{color: blue;}'
				t.className = cls;
				//插入规则
				loadStyleString(css);
			};

			//插入一条css新规则
			var loadStyleString = function(css) {
				var style = document.createElement('style');
				style.type = "text/css";
				try {
					style.appendChild(document.createTextNode(css));
				} catch(e) {//IE
					style.styleSheet.cssText = css;
				}
				document.getElementsByTagName('head')[0].appendChild(style);
			}

		</script>
	</body>
</html>

在输入框中输入要添加的类次数,JS代码会按照次数给div元素添加对应次数的类, 同时会插入一条对应的规则,在代码中,id规则为#test{color:red}, 而类规则为{color:blue},所以如果结论正确,那么div的字体颜色会变为蓝色。

经过测试,发现255是个分水岭,超过255次时,也就是2的8次方,二进制11111111,在chrome下div的文字颜色变成了蓝色, 也就是添加的类为256次时,特殊性变成了1,0,0,0,与ID属性特殊性持平,由于规则在后,故而胜出。

###惨无人道的点此进入DEMO

为了保持完整性,以下在各大浏览器进行了测试:

FF13, chrome22, IE9(包括在其环境下的IE7/8模式),safari5 下,256个类带来的特殊性都等于1个id的特殊性, 然而在opera12,IE9下的怪异模式以及IETester下的IE6/7中,均不会超过id的特殊性, 推测为分别用数字保存,而不是用一个数字按位存储。

###chrome24以上已无此现象,输入65540进行了测试(注意,小心卡死- -!), 发现依然是id优先级最高,说明chrome24+用了单独的数值进行保存

##结论 例子比较极端,正常开发中我想是没有人会弄个256个类的。。。JUST FOR FUN ~ ~ !