
link 和 visited 伪类为什么经常“失效”
因为它们的声明顺序错了。浏览器要求 :link 和 :visited 必须在 :hover、:active 之前定义,否则后两者会覆盖前两者——不是 bug,是 CSS 伪类的层叠规则强制要求。
常见错误现象:a 点击后颜色不变,或鼠标悬停时访问过的链接不响应样式。
-
:link只对未访问的链接生效(且必须是带href的a元素) -
:visited受浏览器安全限制:只能设置有限的样式属性(color、background-color、border-color等,不能读取getComputedStyle,也不能用transition动画) - 如果用了内联
style或!important,可能绕过伪类优先级,导致预期样式不生效
:hover 和 :active 为什么点一下就没了
:active 是“鼠标按下但尚未松开”的瞬间状态,持续时间极短,肉眼几乎不可见——这不是样式没写对,而是它本来就不该“停留”。想延长点击反馈,得靠 JS 配合 class 切换,或者改用 :focus + tabindex 支持键盘操作。
-
:hover在触屏设备上无默认行为(iOS/Android 不触发 hover),需要额外加touchstart监听或用@media (hover: hover)做条件判断 -
:active无法通过纯 CSS 持久化;若想模拟“已点击”状态,必须手动添加 class,比如is-clicked - 移动端真机调试时,
:active可能被系统点击高亮遮盖,可加-webkit-tap-highlight-color: transparent
四种状态的正确书写顺序(LVHA 规则)
必须按 :link → :visited → :hover → :active 顺序写,这是唯一可靠的方式。任何打乱都会导致部分状态被覆盖。
立即学习“前端免费学习笔记(深入)”;
/* 正确 */
a:link { color: #00f; }
a:visited { color: #800; }
a:hover { color: #f00; text-decoration: underline; }
a:active { color: #080; }注意::hover 和 :active 可以同时作用于未访问和已访问链接,所以不需要分别写 a:visited:hover——除非你真要为已访问链接设计不同的悬停色,那才需要单独声明,且仍要放在 :visited 之后。
现代项目里要不要还写全这四个状态
要,但得看场景。无障碍(a11y)和基础可用性要求至少提供 :focus(键盘 Tab 导航),而 :focus 应该和 :active 逻辑一致。很多团队现在用 :focus-visible 替代无条件的 :focus,避免鼠标点击时出现多余轮廓。
- 纯图标链接(无文字)必须有
:hover+:focus提供视觉反馈,否则用户不知道它可点 -
:visited在隐私敏感场景(如医疗、金融)常被禁用或简化,因部分浏览器已限制其样式能力 - 使用 CSS-in-JS 或原子化方案(如 Tailwind)时,别直接写
hover:text-red-500就完事——记得补上visited:text-purple-500和focus:outline,否则默认不包含
真正容易被忽略的是::visited 的样式限制不是临时策略,而是长期安全机制,未来也不会放开。别试图 hack 它来获取访问历史——既做不到,也不该做。










