前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库CSS :hover :focus dynamic pseudo-class
CSS层叠与选择器

hover 和 focus 在使用中有哪些需要注意的地方?

:hover 在鼠标指针移上去时生效,:focus 在元素通过点击或 Tab 获得焦点时生效。最常踩的坑是触屏设备上 :hover 的行为——手机上点击后 :hover 会「粘住」不消失,直到点击其他地方。

前端进阶之旅 · 一题精讲更新于 2026.09.29
CSS#层叠与选择器
先看核心答案读代码示例
理解线索

两种动态伪类的触发方式

  1. :hover鼠标指针进入元素范围时匹配,离开即消失
  2. :focus元素获得焦点时匹配,失焦后消失
  3. :focus-visible只在键盘操作触发焦点时匹配,鼠标点击不触发

:hover 和 :focus 可以同时生效。一个输入框被鼠标悬停并且正在输入时,两个伪类都匹配。

核心回答

先记住这个答案

:hover 和 :focus 都是动态伪类,不改变 DOM 结构,只根据用户交互状态实时匹配。:hover 在鼠标指针进入元素区域时生效,移出后消失。:focus 在元素获得焦点时生效,通过点击、Tab 键或 JavaScript 的 focus() 方法都能触发。两个可以同时生效。

  • :hover 鼠标悬停时生效
  • :focus 获得焦点时生效
  • 触屏设备上 :hover 会粘住
  • :focus-visible 只在键盘聚焦时显示

链接伪类的书写顺序

给 <a> 标签写样式时,:hover 和 :focus 的顺序很重要。如果顺序不对,某些状态的样式会被后面的覆盖掉,看起来像是不生效。业界通用的记忆口诀是 LVHFA。

LVHFA 顺序CSS
a:link    { color: blue; }      /* 未访问 */
a:visited { color: purple; }    /* 已访问 */
a:hover   { color: red; }       /* 鼠标悬停 */
a:focus   { outline: 2px solid; } /* 键盘聚焦 */
a:active  { color: orange; }    /* 正在点击 */

这个顺序之所以重要,是因为这些伪类的优先级相同(都是一个伪类的权重)。当多个状态同时成立时,比如鼠标悬停在一个已访问的链接上,:hover 和 :visited 都匹配。因为优先级相同,后写的赢,所以 :hover 必须在 :visited 后面才能生效。 :active 放最后是因为点击的一瞬间 :hover 和 :active 同时成立,:active 的样式要盖过 :hover。

触屏设备上 hover 会粘住

在手机和平板上,没有鼠标悬停这个动作。用户点击一个元素时,浏览器会模拟一次 :hover,但问题是这个 :hover 不会自动消失,会一直「粘」在那个元素上,直到用户点击了其他地方。

这会导致一个常见的 bug:把重要的交互功能(比如下拉菜单的显示)放在 :hover 上,在手机上就变成了点一下显示、点别处才消失。更好的做法是把 :hover 仅用于视觉增强(比如变色、加阴影),关键交互用 JavaScript 的 click 事件处理。

用媒体查询区分设备CSS
/* 只在有悬停能力的设备上生效 */
@media (hover: hover) {
  .card:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    transform: translateY(-2px);
  }
}

@media (hover: hover) 检测设备是否支持真正的悬停操作。触屏设备上这个条件不成立,:hover 样式就不会生效,避免了粘滞问题。

focus-visible:只在键盘操作时显示焦点样式

:focus 有个烦人的问题:鼠标点击按钮时也会触发 :focus,按钮周围出现一个焦点轮廓。很多设计师觉得这个轮廓不好看,想去掉。但如果直接写 outline: none,键盘用户就看不到焦点在哪了,这是严重的可访问性问题。

:focus-visible 解决了这个矛盾。它只在浏览器认为「用户需要看到焦点指示」时才匹配,通常是键盘操作触发的焦点。鼠标点击不会触发 :focus-visible,所以可以放心地在 :focus-visible 上加轮廓样式,不用担心鼠标用户看到多余的边框。

回答前,多想一步

容易答错的地方

用 hover 做核心交互而不是增强
在手机上 :hover 行为不可靠。如果下拉菜单的展开完全依赖 :hover,手机用户要么无法使用,要么体验很差。:hover 应该只做视觉增强,核心交互用 click 或 :focus。
去掉 focus 样式却不提供替代
button:focus { outline: none; } 这样写会让键盘用户完全看不到焦点在哪个元素上。正确的做法是保留 :focus-visible 的轮廓,只去掉鼠标点击时的样式。
试着用自己的话回答

面试官还会怎么问?

hover 能用在手机端吗?

可以,但行为不一样。手机浏览器会在用户点击时模拟 :hover,而且会「粘住」直到点击别处。所以用 @media (hover: hover) 限制只在真正支持悬停的设备上生效,是更稳妥的做法。

focus 和 focus-within 有什么区别?

:focus 只匹配获得焦点的那个元素本身。:focus-within 匹配的是获得焦点的元素以及它的所有祖先。比如输入框获得焦点时,:focus-within 可以让包裹它的表单组容器也变色。

怎么让一个不可聚焦的元素支持 focus?

HTML 里默认能接收焦点的只有 <input>、<button>、<a> 等交互元素。给其他元素加上 tabindex="0" 就能让它通过 Tab 键获得焦点,:focus 和 :focus-visible 也就能生效了。tabindex="-1" 只能通过 JavaScript 聚焦,不能通过 Tab。

从一道题,走向一组知识

把知识连起来

层叠与选择器

first-line 伪元素能用在哪些元素上?

:hover 与 :focus 属于伪类,::first-line 属于伪元素;组合时要区分状态与文本片段。

层叠与选择器

has() 为什么被叫做"父选择器"?

:has(:focus) 可让父元素根据子元素焦点状态改变样式。

参考资料

  • CSS:层叠与选择器参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 链接伪类的书写顺序
  3. 触屏设备上 hover 会粘住
  4. focus-visible:只在键盘操作时显示焦点样式
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑