:focus伪类没反应主要是被默认outline覆盖、移动端触发条件苛刻或CSS层叠优先级不足;需重置outline、添加inputmode属性并检查样式权重。

focus伪类为什么没反应?检查是否被outline覆盖
很多情况下写好了 :focus 样式但边框没变,其实是浏览器默认的 outline 在捣鬼——它会叠在你自定义的 border 上,甚至完全遮住。更麻烦的是,某些系统(比如 macOS + Safari)对 outline 的渲染逻辑特殊,视觉上像“没生效”。
- 务必显式重置
outline: none,但别只在:focus里加,先在基础输入框样式里设好 - 如果要保留可访问性(推荐),用
outline: 2px solid #007bff替代none,再配合outline-offset: 2px避免和 border 挤在一起 - Chrome/Firefox 对
outline-style: auto的处理不一致,统一改成solid更可控
input:focus 边框变色但太突兀?用 transition 平滑过渡
直接改 border-color 会瞬间跳变,用户感知生硬。加 transition 是最轻量的体验优化,但要注意属性范围和时长取舍。
- 只过渡
border-color和box-shadow,别写all—— 会意外触发重排,尤其在旧版 Safari 上卡顿 - 推荐时长
0.15s:短于 0.1s 不易察觉,长于 0.2s 显拖沓 - 输入框初始状态必须声明
border(哪怕border: 1px solid #ccc),否则:focus的 transition 无法插值
input {
border: 1px solid #ccc;
transition: border-color 0.15s, box-shadow 0.15s;
}
input:focus {
border-color: #007bff;
box-shadow: 0 0 0 3px rgba(0, 123, 191, 0.25);
}
移动端 focus 样式失效?iOS Safari 的 focus 触发条件很苛刻
iOS Safari 默认只给可交互元素(如带 inputmode 或 tabindex 的)触发 :focus,纯 <input type="text"> 在某些 WebView 或禁用缩放页面里可能完全不响应。
- 给 input 加
inputmode="text"属性,明确告诉系统这是文本输入场景 - 避免用
user-scalable=no或maximum-scale=1,它们会抑制 focus 状态更新 - 真机测试时,别只点输入框——试试双击或长按后点击“选择”,有时只有软键盘弹出才真正触发 focus
focus 样式被其他 CSS 覆盖?优先级和继承链容易被低估
最常见的不是写错,而是被更高权重的选择器压住,比如框架的 .form-control:focus 或重置样式里的 input:focus { outline: 0 }。
立即学习“前端免费学习笔记(深入)”;
- 用浏览器开发者工具的“Computed”面板,直接看
border-color最终值从哪来,别猜 - 如果必须提权,用
input[type="text"]:focus比单纯input:focus更具体;但别滥用!important,它会让后续维护变脆弱 - 注意 CSS 顺序:后写的规则覆盖先写的,把你的 focus 样式放在重置样式之后、组件样式之前最稳妥
:focus 表现不一致往往不是语法问题,而是被 outline、移动端策略、CSS 层叠这三者中的某一个悄悄截胡了。调的时候盯住 DevTools 的 “Styles” 和 “Computed” 两个标签页,比反复改代码快得多。










