CSS中:visited链接伪类的怪癖

在对锚点元素 a 设置样式时,一般我们都知道Love or hate规则,即必须按照如下的顺序写选择器:

背后的原理其实很简单,即按照CSS层叠规则,后出现的样式会覆盖先出现的样式。这里我就不多说了。

原本以为记住Love or hate规则就没啥问题了,今天被同事一问,才发现还有东西没搞清楚呢。

问题是这样的,假如有如下HTML代码:

访问过的链接的背景色和字体大小设置都不起作用,而字体颜色设置却起作用了。

然而,如果在 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。完整代码如下:

在浏览器中预览一下,点击各个链接一次,最后效果如下:

结果表明:

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有所不同)的处理方式有关,详见上述解释。

关于我们

蓬勃健康发展的CSTP北京中关村顺义基地是大学生、高中学生实训的最佳选择,国内唯一“国字头”互联网+教育工程。基地设多个专业:电商与新媒体运营、web前端工程师、java软件工程师, UI设计等。

互联网行业的年轻人,你们面对着怎样的职业瓶颈、困惑与未来选择?加入CSTP,让行业专家、技术大牛、教育专家、职业规划专家给你解惑吧!

或搜索ID“cstpcn”

中国软件专业人才培养工程

中关村知尚软件学院

国内唯一“国字头”互联网+教育工程

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180131A07FKS00?refer=cp_1026

同媒体快讯

相关快讯

扫码关注云+社区