CSS 2.1 规范建议,在 A 标签上使用这四个伪类时,声明顺序应为:L-V-H-A。因为只有将 a:hover 放置在 a:link 和 a:visited 之后,才能确保在用户将光标指向 A 元素时,a:hover 内的声明能够覆盖之前 a:link 或 a:visited 中特性名相同的声明。同理,a:active 也应放置在 a:hover 之后,否则 a:active 中特性名相同的声明将被覆盖。
关于 A 元素的更多信息,请参考 HTML 4.01 规范 12.2 The A element 中的内容。
关于链接伪类的更多信息,请参考 CSS 2.1 规范 5.11.2 The link pseudo-classes: :link and :visited 中的内容。
关于动态伪类的更多信息,请参考 CSS 2.1 规范 5.11.3 The dynamic pseudo-classes: :hover, :active, and :focus 中的内容。
根据 CSS 2.1 规范的描述,选择器有其针对性(specificity),可以应用到某一元素的多个规则集中,选择器的针对性越高,该规则集的权重也就越高。针对性相同的,后出现的规则集的权重更高。
针对性由 a b c d 四组数字组成,按照以下的方式计算:
确定针对性的强弱时,根据各组的数字来计算。a 组数字大的针对性更强,当 a 组的数字相同时,比较 b 组数字的大小,以此类推,最终比较结果更大的针对性更强。举例如:
* {} /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */ li {} /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */ li:first-line {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul li {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul ol+li {} /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */ h1 *[id=ok] {} /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */ ul ol li.red {} /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */ li.red.level {} /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */ #xyz {} /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */ style="..." /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */
以上各组选择器,最后一行的内联样式针对性最强,倒数第二行有 ID 选择符的次之,往上的每一行依次减弱,最顶部的通配符针对性最弱。
关于规则集的更多信息,请参考 CSS 2.1 规范 4.1.7 Rule sets, declaration blocks, and selectors 中的内容。
关于针对性的更多信息,请参考 CSS 2.1 规范 6.4.3 Calculating a selector's specificity 中的内容。
在 IE6 IE7(Q) IE8(Q) 中,A 标签的 :visited :hover :active 伪类声明即便没有以 L-V-H-A 的顺序书写,包含这些选择器的规则集中的、相同特性名的声明都会在相对应的行为发生时生效。而其他浏览器则严格按照规范规定的计算方式来确定选择器的针对性及它们的权重。
该问题将造成链接的样式在不同的行为发生时,在各浏览器中的表现不一致。
IE6 IE7(Q) IE8(Q) |
---|
根据规范规定,A 标签的四个常用伪类在计算针对性时的结果是相同的,因此它们的声明顺序应为:L-V-H-A,以确保各规则集中定义的相同特性名的声明可以按照期望的效果覆盖。
分析以下代码:
<html> <head> <style type="text/css"> a {font:bold 50px Verdana;} a:active {color:yellow;} /* [0,0,1,1] */ a:hover {color:blue;} /* [0,0,1,1] */ a:visited {color:green;} /* [0,0,1,1] */ a:link {color:red;} /* [0,0,1,1] */ </style> </head> <body> <div id="b1" class="c1"> <a class="c2" href="#">text</a> </div> </body> </html>
以上代码中的链接文字在各浏览器的不同状态下的颜色:
链接状态 | IE6 IE7(Q) IE8(Q) | 其他浏览器 |
---|---|---|
链接未被访问过(a:link) 鼠标未放到链接上 | red | red |
链接未被访问过(a:link) 鼠标指向链接(a:hover) | blue | red |
链接未被访问过(a:link) 被激活(a:active) | yellow | red |
链接已被访问过(a:visited) 鼠标未放到链接上 | green | green |
链接已被访问过(a:visited) 鼠标指向链接(a:hover) | green | green |
链接已被访问过(a:visited) 被激活(a:active) | green | green |
可见,其他浏览器的表现都是正确的,但在 IE6 IE7(Q) IE8(Q) 中:
因此可以得出初步结论:a:hover 和 a:active 并没有按照规范描述的针对性算法来计算,它们的针对性比 a:link 强,但不比 a:visited 强。
那么是否 a:visited 比 a:hover 和 a:active 要高呢?调整以上代码的 CSS 部分的顺序后再次测试:
a {font:bold 50px Verdana;} a:visited {color:green;} /* [0,0,1,1] */ a:active {color:yellow;} /* [0,0,1,1] */ a:hover {color:blue;} /* [0,0,1,1] */ a:link {color:red;} /* [0,0,1,1] */
链接文字在 IE6 IE7(Q) IE8(Q) 中的不同状态下的颜色(不再测试其他浏览器1):
链接状态 | IE6 IE7(Q) IE8(Q) |
---|---|
链接未被访问过(a:link) 鼠标未放到链接上 | red |
链接未被访问过(a:link) 鼠标指向链接(a:hover) | blue |
链接未被访问过(a:link) 被激活(a:active) | yellow |
链接已被访问过(a:visited) 鼠标未放到链接上 | green |
链接已被访问过(a:visited) 鼠标指向链接(a:hover) | blue |
链接已被访问过(a:visited) 被激活(a:active) | yellow |
注 1:其他浏览器在这种情况下也有兼容性问题,但如果以规范建议的 L-V-H-A 的顺序声明规则集,则可以保证在其他浏览器中的表现一致,因此本文不在对这种情况下其他浏览器中出现的兼容性问题做深入分析。
可见,但在 IE6 IE7(Q) IE8(Q) 中:
再次交换 a:active 与 a:hover 的位置,测试结果相同。
结合以上的结论,可知:在 IE6 IE7(Q) IE8(Q) 中,a:hover、a:active 和 a:visited 并没有按照规范描述的算法来计算它们的针对性,而是根据链接的实际状态来决定使用哪个规则集里的声明。它们三个的针对性比 a:link 强。
事实上,在 IE6 IE7(Q) IE8(Q) 中,a:hover、a:active 和 a:visited 的针对性算法非常特殊,如以下 css 代码:
a {font:bold 50px Verdana;} a:visited {color:green;} /* [0,0,1,1] */ a:hover {color:blue;} /* [0,0,1,1] */ a:active {color:yellow;} /* [0,0,1,1] */ a:link {color:red;} /* [0,0,1,1] */ div a.c2 {color:black;} /* [0,0,1,2] */ div.c1 .c2{color:black;} /* [0,0,2,1] */
看起来最后一行规则集的选择器 'div.c1 .c2' 的针对性要更强,但实际并非如此,链接文字在 IE6 IE7(Q) IE8(Q) 中的不同状态下的颜色为:
链接状态 | IE6 IE7(Q) IE8(Q) |
---|---|
链接未被访问过(a:link) 鼠标未放到链接上 | black |
链接未被访问过(a:link) 鼠标指向链接(a:hover) | blue |
链接未被访问过(a:link) 被激活(a:active) | yellow |
链接已被访问过(a:visited) 鼠标未放到链接上 | green |
链接已被访问过(a:visited) 鼠标指向链接(a:hover) | blue |
链接已被访问过(a:visited) 被激活(a:active) | yellow |
而将最后两行代码注释掉,换成以下代码再试:
a {font:bold 50px Verdana;} a:visited {color:green;} /* [0,0,1,1] */ a:hover {color:blue;} /* [0,0,1,1] */ a:active {color:yellow;} /* [0,0,1,1] */ a:link {color:red;} /* [0,0,1,1] */ /*div a.c2 {color:black;}*/ /* [0,0,1,2] */ /*div.c1 .c2{color:black;}*/ /* [0,0,2,1] */ .c1 a.c2{color:black;} /* [0,0,2,1] */
结果如下:
链接状态 | IE6 IE7(Q) IE8(Q) |
---|---|
链接未被访问过(a:link) 鼠标未放到链接上 | black |
链接未被访问过(a:link) 鼠标指向链接(a:hover) | black |
链接未被访问过(a:link) 被激活(a:active) | black |
链接已被访问过(a:visited) 鼠标未放到链接上 | black |
链接已被访问过(a:visited) 鼠标指向链接(a:hover) | black |
链接已被访问过(a:visited) 被激活(a:active) | black |
可以得出结论:针对性相同的选择器 'div.c1 .c2' 和 '.c1 a.c2'(针对性均为 [0, 0, 2, 1])在 IE6 IE7(Q) IE8(Q) 后者的针对性更强,包含 '.c1 a.c2' 的规则集的权重超过了包含 'a:hover'、'a:active' 和 'a:visited' 的规则集。
将 '.c1 a.c2' 换成针对性更强的 '#b1 a'(针对性为 [0, 1, 0, 1]),结果与上表相同。
严格按照标准的建议,以 L-V-H-A 的顺序声明 A 标签的伪类,以保证在各浏览器中兼容。
当需要以另一组针对性更强的规则集覆盖之前定义的 L-V-H-A 规则集时,请以 L-V-H-A 的顺序重新定义一遍。如以下代码:
<!DOCTYPE HTML>1 <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <style type="text/css"> a {font:bold 50px Verdana;} a:link {color:red;} /* [0,0,1,1] */ a:visited {color:green;} /* [0,0,1,1] */ a:hover {color:blue;} /* [0,0,1,1] */ a:active {color:yellow;} /* [0,0,1,1] */ a.test {color:black;} /* [0,0,2,0] */ </style> <div> <a class="test" href="#">text</a> </div> </body> </html>
注 1:该代码声明的 DTD 触发所有浏览器的标准模式 (S),因此仅 IE6 受此问题影响。
本意是要 class 为 'test' 的 A 标签内的文字永远为黑色,但在 IE6 中将达不到目的。应将样式表部分修改为以下的形式:
a {font:bold 50px Verdana;} a:link {color:red;} /* [0,0,1,1] */ a:visited {color:green;} /* [0,0,1,1] */ a:hover {color:blue;} /* [0,0,1,1] */ a:active {color:yellow;} /* [0,0,1,1] */ a.test:link, a.test:visited, a.test:hover, a.test:active {color:black;} /* [0,0,2,1] */
以确保各浏览器中的效果一致。
操作系统版本: | Windows 7 Ultimate build 7600 |
---|---|
浏览器版本: |
IE6
IE7 IE8 Firefox 3.6 Chrome 4.0.302.3 dev Safari 4.0.4 |
测试页面: | specificity.html |
本文更新时间: | 2010-08-07 |
a :link :visited :hover :active specificity L-V-H-A 链接 伪类 顺序 针对性 特异性 特殊性