:link 和 :visited 仅支持 color 等有限颜色类属性,background 等非颜色属性被浏览器静默屏蔽以保护隐私;LVHA 顺序是硬性要求,否则状态覆盖错乱;href 必须为真实 URL 才匹配;突破限制需用 class + JS + localStorage 替代。

:link 和 :visited 只能靠颜色类属性做有限区分,不是你写错了,是浏览器故意不让你设 background、transition 或 font-weight —— 这是隐私保护机制,不是 bug。
为什么 a:visited { background: #eee } 完全没反应
浏览器主动屏蔽了 :visited 对非颜色属性的渲染。你写的 background、transform、text-shadow、transition 全部被静默丢弃,连报错都不会有。只有以下属性可用:
colorbackground-color-
border-color(包括border-top-color等细分项) outline-colorcolumn-rule-color
注意:background-image、font-weight、opacity 都无效;currentColor 也不能用于推导其他值(比如 border-color: currentColor 在部分浏览器中会被忽略)。
LVHA 顺序不是建议,是防止样式错乱的硬性要求
必须按 a:link → a:visited → a:hover → a:active 的顺序写,否则状态会打架:
立即学习“前端免费学习笔记(深入)”;
- 如果
a:visited写在a:link前面,且两者都设了color,那所有链接(无论是否访问过)都会显示成a:link的颜色 —— 因为后声明的规则覆盖了前面的 - 如果
a:hover写在a:visited后面,悬停时颜色能正常变;但反过来,鼠标移开后可能卡在:visited色,而:hover样式根本没机会生效 - 别用
!important强行压顺序,它会让调试变成猜谜
href 无效时 :link/:visited 根本不匹配
这两个伪类只对真实 URL 生效。以下情况不会触发:
-
href=""或href="#"(空或锚点) -
href="javascript:void(0)"、href="mailto:test@example.com" - 单页应用中用前端路由生成的路径(如
href="/user/profile"),只有浏览器历史里真存过该 URL 才算已访问
测试时务必用完整路径,比如 href="https://example.com/article/123" 或 href="/blog/post-1"。否则你调半天颜色,其实压根没进到伪类作用域。
想加背景、动画或持久化状态?绕开 :visited 本身
真要突破限制,唯一可靠路径是放弃依赖浏览器历史,改用 class + JS 手动管理:
- 监听
click事件,对event.target.closest('a[href]')添加class="visited" - CSS 写
a.visited { background-color: #f5f5f5; color: #666; transition: all .2s; },完全不受限制 - 配合
localStorage存储已访问的href列表,刷新后仍可恢复状态 - 注意:SPA 中
pushState不触发:visited更新,但 JS 方案可以主动同步
最常被忽略的一点是:你以为在调样式,其实是在和浏览器的隐私策略博弈。越早接受这个前提,越少浪费时间查“为什么 background 不生效”。


















