:focus可匹配当前获焦的表单元素,支持input、textarea、select及带tabindex的div;需确保元素可聚焦、避免outline:none、注意样式优先级与disabled状态影响,并兼顾可访问性。

如何用 :focus 选中正在输入的表单元素
直接用 :focus 就能匹配当前获得焦点的表单控件,比如用户刚点进 <input> 或按 Tab 键停在它上面时。它不是只对 <input> 有效——<textarea></textarea>、<select></select>、带 tabindex 的 <div> 同样适用。
<p>常见错误是写成 <code>input:focus 却没加任何样式,结果看不出变化;或者误以为 :focus 能触发 JS 事件(它只是 CSS 伪类,不带行为)。要联动交互逻辑,得配合 focus / blur 事件。
- 确保元素本身可聚焦:原生表单控件默认可聚焦,自定义容器需加
tabindex="0" - 避免仅靠颜色变化做焦点提示——色弱用户可能无法识别,建议叠加边框、阴影或 outline 增强
- 某些浏览器(如旧版 Safari)对
outline有默认样式,重置时别全删,可用outline: 2px solid #007bff替代outline: none
为什么 :focus 有时不生效
最常遇到的是样式被覆盖:比如 Bootstrap 或重置 CSS 中写了 *:focus { outline: none },又没给具体元素补回焦点样式,结果所有 :focus 都“失效”了。另一个原因是元素被禁用:disabled 状态下的 <input> 永远不会触发 :focus,哪怕 JS 强行调用 .focus() 也不行。
- 检查计算样式(DevTools 的 Computed 标签页),确认
:focus规则是否被更高优先级的选择器压制 - 禁用状态用
:disabled单独处理,别指望:focus:disabled—— 它永远不匹配 - 移动端软键盘弹出后,部分 Android 浏览器会短暂丢失焦点,导致样式闪退,这时需监听
focusin事件做兜底
:focus 和 :focus-within 的关键区别
:focus 只作用于自身获得焦点的元素;:focus-within 则只要其任意后代获得焦点,父容器就匹配。例如表单包裹层想高亮整个区域,用 form:focus-within 比给每个子元素单独写 :focus 更省事。
-
:focus-within在 Chrome 60+、Firefox 52+ 支持,IE 完全不支持,需要兼容时得用 JS 模拟 - 不要滥用:嵌套过深的
:focus-within可能导致意外交互,比如点击下拉菜单项时,外层卡片突然变色 - 和
:focus组合使用很实用,例如.input-group:focus-within .input-group-text让前置图标随输入框一起响应焦点
性能与可访问性容易被忽略的点
:focus 样式本身无性能问题,但若搭配复杂动画(比如大范围渐变、box-shadow 模糊扩散),快速切换焦点时可能出现卡顿。更关键的是可访问性:移除默认 outline 后,键盘用户将彻底失去焦点位置感知。
- 别用
outline: 0或outline: none粗暴清空,至少提供等效视觉反馈(如outline: 2px solid #007bff) - 避免仅在
:hover下显示焦点样式——鼠标用户能看到,键盘用户看不到 - 如果用
transition动画,确保时长 ≤ 0.1s,否则焦点移动延迟感明显
真正难的不是写对 :focus,而是让它的表现既符合操作直觉,又不破坏键盘导航流。样式可以改,但焦点顺序、可聚焦性、视觉反馈这三件事,一个都不能少。











