应优先使用 box-shadow 实现柔和发光效果,禁用 outline 后需确保聚焦指示符合 WCAG 对比度要求;移动端须用 JavaScript 动态 class 替代 :focus 伪类以保障兼容性。

focus 时 outline 发光但不干扰布局
outline 默认会在 focus 时加一圈线,但它不占空间、不影响排版,适合做纯粹的视觉提示。但原生 outline 是硬边框,想发光就得改样式。
关键点:用 outline: none 先清掉默认 outline,再用 outline 配合 outline-offset 控制发光距离,避免和 border 混叠:
input:focus {
outline: 2px solid #007bff;
outline-offset: 4px;
box-shadow: 0 0 8px rgba(0, 123, 255, 0.5);
}
注意:outline-offset 为正数时,outline 会向外偏移;负数会向内,容易遮挡内容,慎用。
-
outline不触发重排(reflow),比border更轻量 - 某些浏览器(如旧版 Safari)对
outline的圆角支持弱,发光边缘可能锯齿 - 无障碍访问依赖
outline提供键盘聚焦指示,直接outline: none后必须用box-shadow或其他方式补全视觉反馈
box-shadow 实现柔和发光效果
box-shadow 是更可控的发光方案,能调模糊度、颜色扩散、多层叠加,但要注意它会跟随元素尺寸变化,且在高缩放或 Retina 屏下可能发虚。
推荐写法(兼顾性能与兼容性):
input:focus {
box-shadow:
0 0 0 2px rgba(0, 123, 255, 0.2),
0 0 0 4px rgba(0, 123, 255, 0.1),
0 0 8px rgba(0, 123, 255, 0.3);
}
这样写有三个好处:
- 第一层是紧贴边框的描边,保证聚焦状态清晰可见
- 第二层扩大范围,增强“轮廓感”
- 第三层负责模糊发光,避免单层
box-shadow在深色背景下显得过淡
别用太大的 blur-radius(比如 >20px),否则在低性能设备上滚动或输入时会有卡顿感。
同时用 outline 和 box-shadow 的风险
很多人想两者都保留,结果发现 focus 时出现两圈光晕——其实是 outline 和 box-shadow 叠加后视觉冲突,尤其在暗色主题下特别明显。
真实场景中,应该二选一,或明确分工:
- 用
outline做基础聚焦标识(保障可访问性) - 用
box-shadow做装饰性发光(提升 UI 层级) - 如果禁用了
outline,必须确保box-shadow足够醒目,且满足 WCAG 2.1 对聚焦指示的对比度要求(至少 3:1)
常见错误:outline: none + box-shadow: 0 0 0 3px #007bff → 这种单层描边在深灰背景上几乎不可见,实际测试时务必在真机/暗色模式下验证。
移动端 focus 发光失效怎么办
iOS Safari 和部分安卓 WebView 默认禁用 :focus 样式,除非元素有 tabindex 或是可交互表单控件(input、textarea、select 等)。但即使如此,软键盘弹出后 focus 样式也可能被重置。
解决方案只有两个有效路径:
- 给
input加onfocus="this.classList.add('focused')"+onblur="this.classList.remove('focused')",用 class 控制样式 - 用 JavaScript 监听
focusin/focusout事件,动态添加 class,避开伪类兼容性问题
不要依赖 :active 或 :hover 模拟 focus 效果——它们在触摸设备上行为不稳定,且无法被键盘用户触发。
发光效果本身不是重点,重点是让用户明确知道当前操作焦点在哪。复杂动画或多重阴影反而会让部分用户分心,尤其是有视觉处理障碍的人群。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











