
本文详解如何通过 CSS 自定义属性与 @property 规则,实现径向渐变中圆形尺寸(如色块半径)的真正平滑缩放动画,解决直接修改 radial-gradient() 参数导致的跳变问题,并提供 Firefox 兼容方案。
本文详解如何通过 css 自定义属性与 `@property` 规则,实现径向渐变中圆形尺寸(如色块半径)的真正平滑缩放动画,解决直接修改 `radial-gradient()` 参数导致的跳变问题,并提供 firefox 兼容方案。
在 CSS 中,radial-gradient() 函数的参数(如 #363636 10px, transparent 1px)属于非可动画属性值——浏览器无法对其中的长度值(如 10px)进行插值计算,因此直接在 @keyframes 中修改该数值会导致动画“瞬移”或跳变,而非平滑过渡。
要实现从大圆到小圆的流畅缩放效果,核心思路是:将渐变中可变的长度值抽离为受控的 CSS 自定义属性,并通过 @property 显式声明其类型与动画行为,从而启用 CSS 引擎的原生插值能力。
✅ 正确实现:使用 @property 启用可动画自定义属性
/* 声明可动画的 CSS 变量 --d,类型为 <length> */
@property --d {
syntax: "<length>";
initial-value: 10px;
inherits: false;
}
.loader {
width: 200px;
height: 200px;
background-color: transparent;
/* 在 radial-gradient 中引用变量 */
background-image: radial-gradient(#363636 var(--d), transparent 1px);
background-size: 30px 30px;
animation: loaderout 2s ease-in-out forwards;
}
@keyframes loaderout {
0% { --d: 10px; }
100% { --d: 0.7px; } /* 平滑缩至更小尺寸,避免突兀截止 */
}? 关键点说明:
- @property 是 CSS Houdini 的一部分,需现代浏览器支持(Chrome 103+、Edge 103+、Safari 16.4+)。它告诉浏览器 --d 是一个 <length> 类型的可动画变量,允许在关键帧中做线性/缓动插值;
- background-image 中的 var(--d) 会被实时解析并参与动画计算,确保径向渐变的中心圆半径随时间连续变化;
- 使用 ease-in-out 而非默认 linear,可让缩放起止更自然。
⚠️ 兼容性处理:为 Firefox 提供降级方案
Firefox 当前(截至 v128)尚未支持 @property。为保障基础可用性,可利用 @supports 检测并回退至基于 font-size 的 hack 方案(因 font-size 是天然可动画的 <length> 属性,且其值可被 em 单位引用):
@supports not (--d: 0px) {
.loader {
/* 将 --d 替换为 font-size,并用 em 表达相对长度 */
font-size: 10px;
background-image: radial-gradient(#363636 calc(1em * 1), transparent 1px);
}
@keyframes loaderout {
0% { font-size: 10px; }
100% { font-size: 0.7px; }
}
}? 技巧提示:calc(1em * 1) 等价于 1em,但显式书写便于后续调整比例系数(如 calc(1em * 0.8)),增强维护性。
✅ 完整 HTML 示例
<div class="loader" id="loader"></div>
搭配上述 CSS 即可运行。你将看到一个 200×200px 区域内,由深灰圆点构成的网格背景,所有圆点同步、平滑地从 10px 半径收缩至约 0.7px,形成细腻的“收敛”视觉动效。
? 注意事项总结
- ❌ 避免直接在 radial-gradient() 字符串中硬编码数值并尝试动画化——这永远无法平滑;
- ✅ 务必为 @property 设置 syntax: "<length>",否则浏览器无法执行插值;
- ✅ 初始值(initial-value)应与 0% 关键帧一致,防止首次渲染闪烁;
- ? 生产环境建议结合 @supports 或构建时特性检测(如 Modernizr)做渐进增强;
- ? 可进一步拓展:配合 background-position 动画实现“流动网格”,或用 mask-image + radial-gradient 制作环形遮罩动画。
掌握此模式后,你不仅能平滑控制径向渐变的尺寸,还可迁移至 conic-gradient()、repeating-radial-gradient() 等场景,真正释放 CSS 动画在图形表现上的潜力。

















