可行但需避开陷阱:input不支持伪元素,动画须设为单次播放(如animation: glow 1.2s ease-out 1),用box-shadow扩散半径变化模拟呼吸感,:focus-within更适配父容器光晕,需确保dom结构可聚焦。

focus + animation 实现脉冲光晕动画
直接在 :focus 里用 @keyframes 做脉冲光晕是可行的,但必须避开两个典型陷阱:一是动画不能依赖 ::before/::after 插入内容来“包裹”输入框(input 不支持伪元素插入),二是别把动画写成无限循环却没控制触发时机,导致键盘导航时持续闪烁。
正确做法是让动画只在获得焦点时播放一次,或设为有限次数:
-
input:focus触发后,用animation: glow 1.2s ease-out 1播放单次脉冲,避免干扰 tab 导航 - 动画关键帧中,用
box-shadow的扩散半径变化模拟“呼吸感”,例如从0 0 0 0 rgba(0,123,255,0)到0 0 0 8px rgba(0,123,255,0.4)再回落 - 别在动画里改
border宽度或transform缩放——这会触发重排,光晕抖动明显
:focus-within 是更稳妥的父容器高亮方案
如果你的目标是让整个搜索区域(含图标、清空按钮)一起发光,而不是只高亮 input 自身,:focus-within 比单纯 :focus 更可靠。但它不是加在 input 上的,而是写在它的父容器上。
常见失效原因不是 CSS 写错,而是 DOM 结构不满足可聚焦上下文:
- 父容器如
<div class="search-box"> 必须带 <code>tabindex="-1",否则浏览器不计算:focus-within - 子元素中非输入控件(比如
<button type="button" class="clear-btn"></button>)若本身可聚焦,会提前触发:focus-within;建议统一设tabindex="-1"或aria-hidden="true" - 别用
display: contents包裹子元素——它会让浏览器丢失焦点归属路径,:focus-within永远不生效 - 模糊半径设为
8px–16px:小于6px看不出光晕,大于20px边缘发虚、失焦 - 用
rgba(0, 123, 255, 0.25)这类低透明度色值,避免盖住文字或与背景冲突 - 别写
inset阴影——它往里收,会压住 input 内容;只用外阴影0 0 12px rgba(...) - 多层阴影可增强立体感,例如:
0 0 6px rgba(0,123,255,0.15), 0 0 14px rgba(0,123,255,0.2) - 用
transition处理「进入焦点」和「离开焦点」的平滑衔接(比如边框色渐变 + 阴影淡入淡出) - 用
animation处理「获得焦点瞬间」的强调动作(比如单次脉冲、轻微上浮) - 如果只想要柔和高亮,
transition就够了;动画是锦上添花,不是必需
box-shadow 光晕参数怎么调才不翻车
光晕效果好不好,关键在 box-shadow 的三个数值和颜色透明度,不是加得越多越亮。
推荐组合(适配深色/浅色背景):
transition 和 animation 别混着乱用
同一个 input 上同时定义 transition 和 animation 很容易打架——比如你设了 box-shadow 的过渡,又用 @keyframes 控制同一属性,结果动画卡顿或跳变。
明确分工更稳:
真正容易被忽略的是:移动端软键盘弹出时,:focus 仍会触发,但动画若没控制好时长或循环次数,会在用户打字中途反复闪,干扰输入节奏。











