流光溢出效果的核心原理是利用 linear-gradient 配合 background-size 和 background-position 动画实现光带扫过效果;关键在窄渐变、大背景尺寸与水平位移动画,而非 box-shadow 或 background-color 动画。

什么是流光溢出效果的核心原理
流光溢出按钮不是靠多层阴影或伪元素堆叠出来的“假光”,而是利用 background-image 的线性渐变(linear-gradient)配合 background-size 和 background-position 的动画位移,让高亮色带像一道光扫过按钮表面。关键在于:渐变本身要窄(比如 80px 宽),背景尺寸设得比容器大,再用 animation 推动 background-position 水平移动。
常见错误是直接对 background-color 做动画——它不支持渐变位移,也不会产生“扫过”感;还有人用 box-shadow 模拟,但边缘生硬、无法控制光带角度和长度。
如何写一个可复用的流光动画类
用 CSS 自定义属性(--shine-angle、--shine-width)封装参数,方便不同按钮按需调整:
.btn-shine {
position: relative;
overflow: hidden;
background: #333;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
}
.btn-shine::before {
content: '';
position: absolute;
top: 0; left: -100%;
width: 200px; height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.4),
transparent
);
background-size: 200px 100%;
animation: shine 2s infinite;
}
@keyframes shine {
100% { left: 100%; }
}
注意点:
-
overflow: hidden必须加在按钮本身,否则光带会溢出边框 -
::before的width要略大于预期光带长度(比如设200px),否则动画末尾会露黑边 - 动画时间
2s是平衡感较好的起点;太快显得躁,太慢失去“流”感 - 如果按钮有圆角,
border-radius要同时加给按钮和::before,否则光带直角切穿圆角
为什么 background-position 动画比 left 更推荐
left 位移依赖绝对定位,且在缩放、flex 居中等场景下容易错位;而用 background-position 配合 background-size 更稳定:
.btn-shine-v2::before {
content: '';
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.6),
transparent
);
background-size: 200px 100%;
background-position: -200px center;
animation: shine-pos 2.5s infinite;
}
@keyframes shine-pos {
100% { background-position: 200px center; }
}
这样写的好处:
- 不用算
left的起始偏移,适配响应式更鲁棒 - 光带始终居中垂直,哪怕按钮高度变化也不偏移
- 可以轻松改成斜向流光:把
90deg换成45deg,background-size改为300px 300px - 部分旧版 Safari 对
left动画渲染有闪烁,background-position兼容性更稳
移动端点击反馈与性能陷阱 流光动画在 iOS Safari 上可能被判定为“非合成层”,导致卡顿。解决方法很明确:
强制开启硬件加速,但别滥用 transform: translateZ(0) —— 它会让整个按钮重绘,反而更慢。正确做法是只对伪元素加:
- 给
::before加will-change: background-position(仅在动画触发时) - 或更稳妥地:用
transform: translate3d(0, 0, 0)+backface-visibility: hidden组合 - 避免在
:active状态里同时启动流光和缩放动画,iOS 会丢帧;建议流光常驻,点击只改背景色或阴影 - 如果按钮在滚动区域里频繁进入视口,用
@media (prefers-reduced-motion: reduce)关掉动画,这是 WCAG 合规要求,不是可选项
rgba(255,255,255,0.4),结果看不见。得用 color-scheme: light dark 配合自定义属性,或者直接读取 currentColor 做亮度微调。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











