:focus能用但常失效,主因是outline遮盖、border未定义、dom未挂载、显隐控制静默聚焦、css权重覆盖;须写三行基础css:定义完整border、清除outline、声明transition,再写:focus样式。

直接说结论: :focus 能用,但单独写 input:focus { border-color: blue; } 大概率没反应——不是你代码错,是被 outline 盖住了、初始 border 没定义、或元素根本没触发聚焦逻辑。
为什么 input:focus 边框变色总失效?
失效主因从来不是伪类写法本身。常见真实场景包括:
-
outline默认存在且层级高于border,颜色再改也看不见 - 原始样式写了
border: none;或压根没设border,border-color变了但宽度为 0,等于没画 - 元素是 Vue/React 动态渲染的,CSS 已加载,DOM 还没挂载完成,
:focus规则不匹配 - 用了
display: none或visibility: hidden控制显隐,focus()和autofocus全部静默 - 多个
input:focus规则权重相同,后写的覆盖了前写的——打开开发者工具的 “Computed” 面板一眼就能确认
必须写的三行基础 CSS 才能真生效
别跳过这三步,缺一不可:
- 默认状态必须定义完整边框:
input { border: 1px solid #ccc; }(不能只写border-color) - 立刻清掉默认 outline:
input { outline: none; }(推荐写在常态,非:focus中) - 过渡必须放在常态里,且只动必要属性:
input { transition: border-color 0.2s ease, box-shadow 0.2s ease; }
然后才是聚焦样式:input:focus { border-color: #007bff; box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25); }。用 box-shadow 替代加粗 border-width,可避免布局抖动。
移动端 iOS Safari 点击无反馈?加 ontouchstart 或 cursor:pointer
iOS Safari 默认压制非交互元素的焦点渲染逻辑,哪怕它是 <input>。纯 CSS :focus 在真机上点一下可能完全不动。
- HTML 层加空事件:
<input type="text" ontouchstart="">,唤醒底层聚焦机制 - CSS 层加提示:
input { cursor: pointer; },让系统识别为可点击目标 - 微信 WebView 更激进,可能直接忽略纯 CSS
:focus,得用 JS 监听focus事件动态加 class - 模拟器常骗人,真机测试必须用手点
键盘聚焦和鼠标聚焦要分开处理
用户按 Tab 导航时需要强对比轮廓,点鼠标时反而觉得多余。硬套 :focus 会两头不讨好。
- 用
:focus-visible是当前最稳妥解法:input { outline: none; } input:focus-visible { outline: 2px solid #007bff; outline-offset: 2px; } - 旧浏览器(IE、老版 Safari)不支持
:focus-visible,会自动回退到:focus,所以仍需保留兼容写法 - 别用 JS 监听
keydown判断是否按了 Tab 再加 class——不可靠,且破坏原生焦点管理 - 暗色模式下
border-color很可能和背景融成一片,@media (prefers-color-scheme: dark)里重定义是刚需,不是可选项
真正麻烦的不是怎么写,而是哪些地方不能省:outline 清了得补反馈、border 宽度得提前占位、transition 得写在常态、移动端得手动“唤醒”——漏掉任意一个,用户就可能在键盘导航时彻底失焦。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











