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

因为浏览器主动拦截,防止通过样式差异探测用户访问历史——这不是兼容性问题,而是强制执行的隐私保护策略。
浏览器为什么封禁大部分:visited样式
核心目的是阻断“历史嗅探”(history sniffing)攻击:恶意网站曾利用 CSS 属性变化(比如background-image、font-size、display)配合 JavaScript 测量布局或渲染差异,反推出用户是否访问过某链接(如银行、社交平台等敏感域名)。现代浏览器(Chrome 136+、Firefox、Safari)直接从解析层剥离所有高风险能力,不是“不支持”,是“不允许”。
:visited真正能改的属性有哪些
仅限以下颜色类属性,且必须用具体值(不能用 currentColor、transparent 或带 alpha 的 rgba()):
color-
background-color(仅纯色,linear-gradient和url()静默失效) -
border-color及其细分项(如border-top-color) -
outline-color、column-rule-color、text-decoration-color -
fill和stroke(仅对内联 SVG 中带href的元素有效)
所有涉及尺寸、位置、图像、动画、过渡、滤镜、阴影的属性(如 transform、opacity、transition、background-image)一律被忽略,DevTools 中会显示为 strikethrough 灰线。
为什么写了color却没反应
即使用了合法属性,常见失效原因包括:
- 链接 URL 实际不同:
/article/123和/article/123?ref=share被视为两个独立地址 - 测试环境用
file://协议——所有主流浏览器完全禁用该协议下的:visited - 未真实跳转并返回:需用户点击该链接 → 跳转目标页 → 再返回原页,浏览器才完成历史匹配
- CSS 优先级冲突:
a[href^="https"]或a.nav-link等高权重规则覆盖了a:visited - 伪类顺序错误:若
a:hover写在a:visited之前,且两者都设了color,悬停时会按声明顺序覆盖,导致已访问链接悬停后“回退”颜色
JS 读不到:visited的真实状态
这是同步封禁的一环:
-
getComputedStyle(el).color永远返回a:link的值,无论链接是否访问过 -
el.matches(':visited')在 Chrome/Firefox 中已废弃,始终返回false - 任何试图通过布局测量(
offsetWidth)、样式注入或伪元素内容探测的侧信道方法,均被浏览器防御机制彻底拦截
真正难的不是写对代码,而是接受这个事实:你无法绕过,也不该绕过。设计上用 color 做最小可行区分,或转向服务端状态 / localStorage 标记,才是实际路径。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











