浏览器限制 :visited 仅支持 color、outline-color、border-color 和 background-color 等少数属性,其他如 font-weight、opacity 均无效;且颜色可能被降级以防止指纹追踪,跨源链接也不生效。

为什么 :visited 看不到颜色变化?
浏览器出于隐私保护,从 Chrome 16 / Firefox 4 开始大幅限制 :visited 的样式能力——你只能安全地设置 color、outline-color、border-color(及简写如 border-bottom-color)和 background-color;其他属性如 display、font-size、visibility 或 transition 都会被忽略,且不会报错。
常见错误现象:a:visited { font-weight: bold; } 写了也没用;a:visited { opacity: 0.7; } 完全不生效;甚至加了 !important 也无济于事。
- 只用
color最稳妥,比如a:visited { color: #666; } - 避免依赖
:visited做布局或动画,它不是状态切换的通用工具 - 测试时记得真点击过链接(不能只靠 DevTools 强制触发伪类)
:visited 的颜色必须比 :link 暗?
不是必须,但浏览器会主动降级部分颜色值:如果你设 a:visited { color: rgb(255, 0, 0); },Chrome 可能悄悄把它渲染成更灰暗的近似色(比如 rgb(180, 0, 0)),这是防指纹追踪的强制行为,无法绕过。
使用场景:适合做视觉提示,比如“已读/未读”区分,但别指望精确还原设计稿里的高饱和色。
立即学习“前端免费学习笔记(深入)”;
- 优先选中性灰阶(如
#777→#999)或低饱和度蓝/紫 - 避免用
hsl()或rgba(),部分浏览器解析不稳定 - 如果需要强对比,改用文字前缀(如
[已读])或图标,而非仅靠颜色
怎么让外部链接也支持 :visited?
默认情况下,跨源链接(比如 https://example.com)的访问状态无法被当前页面读取,所以 :visited 不生效——这不是 bug,是同源策略的延伸。
这意味着:你网站内跳转的链接能记状态,但用户点过知乎、GitHub 的链接,你的页面里是看不到的。
- 只有同协议 + 同域名 + 同端口的链接才受
:visited控制 - 路径不同没关系(
/a和/b都算同源) - 不要试图用 JS 读取
getComputedStyle(link).color来判断是否访问过,返回值已被浏览器脱敏
替代方案:什么时候该放弃 :visited?
当你要支持“多设备同步已读状态”“按用户账号记录”“点击后持久化标记”,:visited 就彻底不合适了——它只存在当前浏览器、当前用户、当前 Cookie 分区的本地记忆里,关掉标签页就丢。
性能影响几乎为零,但兼容性陷阱太多:Safari 对 :visited 的限制更激进,某些版本连 background-color 都禁用。
- 需服务端参与的状态,请用
localStorage+ URL 哈希或后端接口标记 - 要跨设备,必须走登录态 + 用户 ID + 接口同步
- 纯静态博客?老老实实用
:visited配color,别折腾
真正麻烦的不是怎么写,而是它看起来像能做更多事——结果你调了半天发现浏览器在背后悄悄改了你的颜色、屏蔽了你的 transition、还拒绝告诉你为什么。


















