关于 `:visited` 伪类

最近读到了 Kev Quirk 关于 :visited 样式的文章,我认为有必要跟进实现。不过在实现的过程中,我还是注意到了一些非常有趣的问题。

修改链接颜色很简单,直接指定 a:visited 的 color 样式就可以了。不过,我发现如果简单地套用浏览器默认样式会带来一个很尴尬的问题——

蓝紫组合对色弱人士不友好

标准的浏览器行为是:新链接使用蓝色表示;访问过的链接用紫色表示,也就是:

蓝色样块

紫色样块

但如果你是红绿色弱或色盲的话,你实际看到的样块颜色会类似于这样:

蓝色样块

紫色样块

这两个样块之间的颜色差异不甚明显。

一般这种问题的通行解法是:不要让信息只通过一个渠道传递。即使是纯视觉的元素,也可以通过明度和色度两个通道来传递。具体的,我们可以考虑给这两种不同的链接安排不同的下划线样式,或者在链接尾部追加一个小图标,或者……

但是 :visited 是特殊伪类

因为它携带用户的隐私信息,所以无论是指定不同的下划线样式,还是 ::after, 甚至 >, +, :has() 等等组合子都会被浏览器静默地忽略[1]。CSS 唯一能够修改的,只有颜色,甚至连 Alpha 通道都无法修改。

借助 JavaScript 的力量也是不行的。getComputedStyle(.) 总是会返回链接未被访问过的样式;document.querySelector(.) 也不会匹配 :visited 选择子[2]。毕竟,开放这项能力相当于允许 JavaScript 脚本无感地探测用户是否访问过给定的网站,这个能力可真是太强大了。

在 2022 年,我撞到了 Varun Biniwale 的伪装成验证码的历史嗅探实现。不过比较遗憾的是(或者说幸好),这个演示里所使用的技巧并不能绕开浏览器针对于 :visited 选择器的限制;也无法用于给已访问的链接添加更多新的样式。

那么,这意味着一件事:想要改善可访问性,我们就必须跳脱出浏览器的默认颜色表。

挑选更友好的色彩搭配

好在「什么颜色搭配是色盲友好的」这个问题已经有现成答案了。参考 NCEAS 给出的色彩搭配[3]和 Dawn Bringer 32 色盘表,我最终决定了使用如下颜色值:

a {
  color: light-dark(#306082, #cbdbfc);
}

a:visited {
  color: light-dark(#45283c, #eec39a);
}

虽然看起来有点怪(尤其是在暗色主题下),但这样的颜色搭配可以照顾到红绿蓝三种可能的情况。可惜的是受限于文字对比度要求,我实在是没法照顾全色盲/灰度显示器上的阅读体验了。


参考与注释

  1. Mozilla. :visited CSS pseudo-class[F/OL]. MDN. (2026-09-10)[2026-09-26]. https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:visited. ↩︎
  2. Mozilla. Privacy and the :visited selector[F/OL]. MDN. (2025-11-07)[2026-09-26]. https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Selectors/Privacy_and_:visited. ↩︎
  3. Phillips A. Colorblind Safe Color Schemes[EB/OL]. NCEAS Science Communication Resource Center. (2022-06-29)[2026-09-28]. https://www.nceas.ucsb.edu/sites/default/files/2022-06/Colorblind Safe Color Schemes.pdf. ↩︎
添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论