关于 `: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);
}
虽然看起来有点怪(尤其是在暗色主题下),但这样的颜色搭配可以照顾到红绿蓝三种可能的情况。可惜的是受限于文字对比度要求,我实在是没法照顾全色盲/灰度显示器上的阅读体验了。
参考与注释
- Mozilla.
:visitedCSS pseudo-class[F/OL]. MDN. (2026-09-10)[2026-09-26]. https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:visited. ↩︎ - 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. ↩︎
- 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. ↩︎