浏览器禁用:visited大部分样式是为阻断历史嗅探攻击,仅允许color、background-color(纯色)、border-color等少数颜色属性,其他如background-image、transition等均被静默忽略。

为什么浏览器直接禁用 :visited 的大部分样式
因为这是硬性隐私保护策略,不是兼容性问题或浏览器 bug。现代浏览器(Chrome 136+、Firefox、Safari)在解析 CSS 时就剥离了所有高风险属性,防止恶意网站通过样式差异探测用户访问历史——比如判断你是否登录过银行、社交平台或医疗网站。
攻击原理很简单:脚本可批量生成带不同 href 的 <a> 元素,再用 getComputedStyle() 或布局测量(如 offsetWidth)比对渲染结果,反推出哪些链接已被访问。浏览器选择“一刀切”禁用,而非打补丁。
:visited 真正能改的 CSS 属性有哪些
仅限以下颜色类属性,且值必须是不带透明度的纯色(rgba()、hsla()、currentColor、transparent 全部失效):
color-
background-color(仅支持#666、rgb(102, 102, 102)这类纯色;linear-gradient和url()静默忽略) -
border-color及其细分项(如border-top-color),但border-width、border-style不行 -
outline-color、column-rule-color、text-decoration-color -
fill和stroke(仅对内联 SVG 中带href的<a>有效)
所有其他属性——包括 font-size、display、transform、opacity、transition、background-image——都会被 DevTools 显示为 strikethrough 灰线,且不触发重排、重绘或任何 JS 可观测行为。
立即学习“前端免费学习笔记(深入)”;
为什么写了 color 却没反应
即使用了合法属性,常见失效原因包括:
- 链接 URL 实际不同:
/post/1和/post/1?ref=share被视为两个独立地址 - 测试环境用
file://协议——所有主流浏览器完全禁用该协议下的:visited - 未真实跳转并返回:需用户点击该链接 → 跳转目标页 → 再返回原页,浏览器才完成历史匹配
- CSS 优先级冲突:
a.nav-link或a[href^="https"]这类高权重规则覆盖了a:visited - 伪类顺序错误:若
a:hover写在a:visited之前,且两者都设了color,悬停时会按声明顺序覆盖,导致已访问链接悬停后“回退”颜色
为什么 JavaScript 读不到 :visited 的真实状态
这是同步封禁的一环:getComputedStyle(el).color 永远返回 a:link 的值,无论链接是否访问过;el.matches(':visited') 在 Chrome/Firefox 中已废弃,始终返回 false。
任何试图绕过的侧信道方法(比如注入伪元素、监听尺寸变化、比对渲染时间)均被浏览器防御机制彻底拦截。你无法靠前端代码确认一个链接是否真的被访问过——这不是技术限制,而是设计共识。
真正难的不是写对代码,而是接受这个事实:你无法绕过,也不该绕过。设计上用 color 做最小可行区分,或转向服务端状态下发、localStorage 记录点击等可控方案。


















