Material UI的聚焦光晕需用多层rgba阴影(如0 0 4px rgba(33,150,243,0.5), 0 0 16px rgba(33,150,243,0.2))配合transition声明在非聚焦态、outline: none及主题适配,单层box-shadow会显生硬。

为什么:focus加box-shadow后看起来不像Material UI的光晕
Material UI 的聚焦光晕不是单层硬边阴影,而是带透明度、中等模糊(12–20px)、轻微外扩的柔和发光效果。直接写 box-shadow: 0 0 5px #2196f3 会显得生硬发虚,或在深色背景上不可见。关键在三个参数:模糊半径、rgba 透明度、以及是否叠加内层亮边。
常见错误现象:box-shadow 值被框架(如 Bootstrap)的 .form-control:focus 覆盖;iOS Safari 渲染模糊值偏弱;阴影颜色没适配主题背景(比如浅色主题用 rgba(33, 150, 243, 0.3),深色主题需提高透明度或改用更亮蓝)。
- 推荐基础写法:
box-shadow: 0 0 12px rgba(33, 150, 243, 0.3); - 进阶双层写法(更接近 MUI):
box-shadow: 0 0 4px rgba(33, 150, 243, 0.5), 0 0 16px rgba(33, 150, 243, 0.2); - 务必搭配
outline: none,否则 Chrome/Safari 可能同时显示默认轮廓和自定义阴影
如何让:focus阴影过渡更顺滑,避免“闪一下”
Material UI 的焦点动画是缓入缓出、持续约 200ms 的渐变过程。纯 CSS 实现的关键不是在 :focus 里写 transition,而是在**非聚焦的原始状态**中声明过渡属性,让浏览器自动补间。
容易踩的坑:只给 :focus 加 transition,失焦时无过渡;或用了 all 0.2s 导致字体、尺寸等无关属性也被动画化,引发布局抖动。
立即学习“前端免费学习笔记(深入)”;
- 正确写法(放在基础样式里):
input { transition: box-shadow 0.2s ease-in-out; } - 如果同时改边框色,合并声明:
transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out; - 别对
outline做 transition —— 它不支持平滑变化,且 Material UI 已彻底移除 outline
移动端 iOS Safari 上:focus阴影不明显怎么办
iOS Safari 对 box-shadow 的模糊渲染比桌面端保守,尤其在低分辨率屏或旧机型上,12px 模糊可能看起来像 6px。这不是 bug,是 WebKit 的渲染策略差异。
使用场景:表单在 iPhone 全屏 WebView 或 PWA 中运行时,用户反馈“点进去没反应”。DevTools 里能看到样式生效,但肉眼难察觉。
- 实操建议:对 iOS 设备单独加大模糊值,例如
@supports (-webkit-appearance: none) { input:focus { box-shadow: 0 0 20px rgba(33, 150, 243, 0.25); } } - 避免依赖阴影做唯一焦点提示 —— 同时微调边框色或背景亮度(比如
background-color: #fff8f0),形成组合反馈 - 测试要点:真机 > 模拟器 > DevTools 响应式模式;iOS 15.4+ 支持
caret-color,可同步高亮光标增强感知
和:focus-visible混用时阴影该给谁
Material UI 默认对所有焦点触发都显示光晕(包括鼠标点击),但如果你项目已启用键盘优先策略,就会遇到 :focus 和 :focus-visible 冲突:鼠标点输入框时,:focus-visible 不匹配,阴影消失。
性能影响很小,但逻辑容易混乱。关键是明确设计意图:MUI 风格本身不区分触发方式,所以优先用 :focus;若必须兼顾无障碍规范(WCAG 2.4.7),再用回退方案。
- 统一行为(推荐):
input:focus { outline: none; box-shadow: ...; }—— 简单直接,符合 MUI 视觉一致性 - 键盘专属(合规要求):
input:focus-visible { box-shadow: ...; } input:focus:not(:focus-visible) { outline: none; } - 兼容性兜底:Safari 15.4 以下不支持
:focus-visible,此时仅靠:focus即可覆盖全部场景
最常被忽略的是:阴影颜色没随主题动态切换。深色模式下硬写 rgba(33, 150, 243, 0.3) 可能完全看不见,得配合 @media (prefers-color-scheme: dark) 调整透明度或色相。


















