CSS中:visited链接伪类的怪癖
来源:互联网 发布:哨子办公软件 编辑:程序博客网 时间:2024/06/08 23:21
在对锚点元素 a 设置样式时,一般我们都知道 Love or hate 规则,即必须按照如下的顺序写选择器:
a { ... }a:link { ... }a:visited { ... }a:hover { ... }a:active { ... }
背后的原理其实很简单,即按照CSS层叠规则,后出现的样式会覆盖先出现的样式。这里我就不多说了。
原本以为记住 Love or hate 规则就没啥问题了,今天被同事一问,才发现还有东西没搞清楚呢。
问题是这样的,假如有如下HTML代码:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <style> a { font-size: 3em; } a:link { color: red; } a:visited { color: blue; background-color: red; font-size: 30px; } a:hover { color:black; background-color: gray; font-size: 30px; } a:active { color:orange; background-color: blue; font-size: 30px; } </style></head><body> <a href="#">Hello</a></body></html>
意图是让访问过的链接背景色变为红色,字体大小变为30px。然而,打开浏览器预览,点击链接之后,结果却是如下这样子:
访问过的链接的背景色和字体大小设置都不起作用,而字体颜色设置却起作用了。
然而,如果在 a 或者 a:link规则中设置background-color,那么a:visited规则中设置的background-color就会起作用。不过,即使在 a 或者 a:link规则中设置了font-size,a:visited规则中的font-size也不会起作用。而对于a:hover和a:active规则却没有这些奇怪的现象。
带着疑问,打开了CSS3选择器规范:Selectors Level 3。有关链接伪类的也只有一小段:
其中有一段话引起了我们的注意:
注意:样式表的作者可能会在没有用户同意的情况下,滥用 :link 和 :visited 伪类,以判断用户访问过哪些网站。因此,用户代理可能会把所有链接当作未访问的链接,或者实现其它措施,以保护用户隐私,同时以不同方式渲染访问过的以及未访问过的链接。
难道这玩意还跟用户隐私保护有关系?可是规范也太简单了,根本没法理解。去 MDN 查一下,看有没有详细解释。在 MDN CSS参考指南中对 :visited 的解释中发现了一段话:
中文翻译过来就是:
注意:出于隐私的考虑,浏览器严格限制用此伪类选择的元素应用的样式:只能应用color,background-color, border-color, border-bottom-color, border-left-color, border-right-color,border-top-color, outline-color, column-rule-color, fill 和 stroke。还要注意,alpha 组件会被忽略,会用非visited规则的alpha组件替换(除了透明度为 0 时,此时整个颜色都被忽略,并用非 visited规则之一)。
虽然颜色可以被修改,不过方法 getComputedStyle 会撒谎,总是返回非 visited 颜色值。
前一句的意思还能明白,就是:a:visited 规则上只能设置上面指出的几种属性,font-size 不在其中,所以在 a:visited 规则上设置 font-size 是不起作用的。好了,这个明白了。
不过,明明是允许设置 background-color,为嘛一定要在 a 或者 a:link 上设置了 background-color 后,a:visited 上设置的 background-color 才会生效呢?是不是跟这个什么 alpha 组件有关系呢?
这个 alpha 组件是什么意思呢?我们知道CSS3中颜色可以用RGBA表示法。其中,R代表红色值,G代表绿色值,B代表蓝色值,而A代表alpha值。这个alpha值用来表示颜色的透明度,取值是0到1之间,0代表透明,1代表不透明。那么“alpha 组件会被忽略,会用非visited规则的alpha组件替换(除了透明度为 0 时,此时整个颜色都被忽略,并用非 visited规则之一)” 的意思就是:如果在:visited规则上设置的颜色透明度为0,即transparent,那么就会用未访问过的规则完全替换它;如果颜色透明度不为0,那么就会用未访问过的规则的颜色透明度来替换这个alpha值。
我们用代码来证明一下。设置四个链接,分别设置未访问过的链接的颜色透明度为0,0,1,1,对应的访问过的链接的颜色透明度0,1,0,1。完整代码如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <style> a:link.a1 { background-color: rgba(0,1,0,0); } a:visited.a1 { background-color: rgba(255,0,0,0); } a:link.a2 { background-color: rgba(0,255,0,0); } a:visited.a2 { background-color: rgba(255,0,0,1); } a:link.a3 { background-color: rgba(0,255,0,0.2); } a:visited.a3 { background-color: rgba(255,0,0,0); } a:link.a4 { background-color: rgba(0,255,0,1); } a:visited.a4 { background-color: rgba(255,0,0,1); } </style></head><body> <a href="#" class="a1">Hello1</a> <a href="#" class="a2">Hello2</a> <a href="#" class="a3">Hello3</a> <a href="#" class="a4">Hello4</a></body></html>
在浏览器中预览一下,点击各个链接一次,最后效果如下:
结果表明:
1)如果未访问过的链接的颜色是透明的,那么访问过的链接的颜色也一定是透明的,所以链接a1、a2的背景色是透明的。
2)如果未访问过的链接的颜色是不透明的,而访问过的链接的颜色是透明的,那么原本访问过的链接背景色是不会出来的,但是因为alpha值会被未访问过的链接的alpha值替换,所以背景色也出来了(注意:FireFox会用未访问过的链接的RGB完全替换访问过的链接的RGB,而Chrome、Safari依然采用访问过的链接的RGB)。
3)如果未访问过的和访问过的链接的颜色都是不透明的,那么采用的是访问过的链接的RGBA中alpha值会被未访问过的链接的RGBA的alpha值替换,RGB保持不变。
至此问题就都搞清楚了。
总结:
1)浏览器根据隐私策略,会限制:visited链接伪类样式规则中出现的属性,只有下列的属性才能被应用到已访问链接:
color
background-color
border-color (及其子属性)
outline-color
fill 和 stroke 属性的颜色部分
2)如果要给已访问链接添加颜色属性,未访问链接必须添加对应的颜色属性,并且其透明度不能为0。而已访问链接的最终颜色,跟浏览器(FireFox与Chrome、Safari、IE有所不同)的处理方式有关,详见上述解释。
- CSS中:visited链接伪类的怪癖
- CSS伪类链接:点击某一个链接后,刷新页面,其他所有从没点击过的链接都变成a:visited中定义的颜色
- css中link visited hover active伪类的书写顺序
- CSS中定义链接样式的四个伪类
- a标签的四个css伪类(link、visited、hover、active)样式理解
- Css中的伪类link,visited,hover,focus,active
- CSS中-visited的隐私保护
- CSS中-visited的隐私保护
- 链接 <a> 的CSS伪类不起作用
- CSS中常用的四种链接状态:a:link、a:visited、a:hover及a:active
- CSS链接、列表、伪类
- CSS伪类链接[译转]
- CSS A link hover active visited伪类超链接锚文本样式教程
- CSS A link hover active visited伪类超链接锚文本样式应用用法案例
- css伪类选择器,:link、:visited、:focus、:hover、:active、:first-child
- css中的伪类 之 控制链接的样式。
- div+css处理链接的:link,:visited,:hover,:active四种状态
- div+css处理链接的:link,:visited,:hover,:active四种状态
- 如何在git上clone别人的项目、提交代码以及更新最新代码
- 重定向 重写
- 【舞伴问题 -- 链队列实现】
- 如何绕过面试题中的小坑
- Jedis常见异常汇总
- CSS中:visited链接伪类的怪癖
- Mysql 字段拼接
- TP5 小知识
- 如何用 css 修出好看的照片
- 牛客网---2016---搜狐发奖金
- DrawerLayout 侧滑菜单
- 记录一次spring mvc事务不起作用的解决方案
- (算法分析Week10)Letter Combinations of a Phone Number[Medium]
- Python文件操作