用 :link 和 :visited 区分链接状态是提升导航可访问性的最基础有效手段,但必须遵循 lvha 顺序且仅能通过 color 等有限属性设置已访问样式,因现代浏览器为防历史探测而强制限制 :visited 的样式范围。

:link 和 :visited 区分链接访问状态,是提升导航可访问性的最基础、最有效手段之一;但必须按 LVHA 顺序书写,且不能依赖 :visited 控制非颜色类样式——否则在现代浏览器里根本不会生效。
为什么 :visited 只能改颜色,改了别的也白搭
这不是 bug,是浏览器主动限制。Chrome、Firefox、Safari 都强制只允许 :visited 修改有限的几个属性:color、background-color、border-color、outline-color,以及它们的透明度变体(如 rgba())。其他任何尝试——比如 font-size、text-decoration、transform、background-image——都会被静默忽略。
这是为了防止网站通过样式探测用户浏览历史(例如:构造一堆隐藏链接,再用 JS 读取 getComputedStyle 判断是否被访问过)。
- 别写
a:visited { font-weight: bold; }—— 它不生效 - 别指望
a:visited { background: url(…); }能显示图片背景 - 如果用了
filter或opacity,也大概率被忽略(不同浏览器行为不一致,应视为不可靠)
:link 和 :visited 必须按 LVHA 顺序写,否则 hover 会失效
LVHA 是 Link → Visited → Hover → Active 的缩写,不是建议,是实际生效的层叠逻辑。CSS 规则后写的会覆盖前面同优先级的规则,而 :hover 和 :active 本身没有更高特异性,所以如果把 :hover 写在 :visited 前面,鼠标悬停时可能仍沿用 :visited 的颜色,导致“悬停没反应”。
- ✅ 正确顺序:
a:link→a:visited→a:hover→a:active - ❌ 错误示例:
a:hover { color: red; }放在a:visited { color: #666; }前面,悬停时颜色可能卡在灰色 - 注意:如果用了更具体的选择器(如
nav a:visited),要确保 hover 选择器同样具体,否则优先级可能翻车
可访问性关键点:颜色对比度必须达标
仅靠“蓝色 vs 灰色”不等于可访问。WCAG 2.1 要求普通文本的对比度至少 4.5:1。很多默认的 #666 在白色背景上只有约 3.8:1,对低视力用户几乎无法识别已访问状态。
- 推荐用工具检测:WebAIM Contrast Checker 或浏览器 DevTools 的无障碍面板
- 安全配对示例:
a:link { color: #0066cc; }(对比度 7.2:1) +a:visited { color: #5a5a5a; }(对比度 4.7:1) - 避免纯灰(
#999)、浅紫(#e6e6ff)等弱对比组合 - 不要只靠颜色区分——可叠加下划线变化(
a:link { text-decoration: underline; },a:visited { text-decoration: none; }),但注意:下划线本身不能用于:visited单独控制(部分浏览器允许,但不保证)
导航中真实可用的最小实践模板
下面这段代码能在所有现代浏览器中稳定工作,且满足基本可访问性要求:
a:link {
color: #0066cc;
text-decoration: underline;
}
a:visited {
color: #5a5a5a;
}
a:hover {
color: #004080;
text-decoration: underline;
}
a:active {
color: #002a55;
}
关键细节:
- 所有颜色都经过对比度验证(白底)
- 未访问和已访问都保留下划线,hover/active 只强化颜色,不取消下划线(避免移除视觉线索)
- hover 和 active 使用更暗的同色系,提供明确反馈,且不破坏访问状态识别
- 没用
font-weight或border等不可靠属性
真正容易被忽略的,不是怎么写,而是忘了验证——哪怕一行 color 改得再准,如果背景是浅灰或图片,对比度就崩了。每次上线前用 DevTools 的「Contrast」标签扫一遍导航链接,比重写三遍 CSS 更省时间。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











