radial-gradient 中不能直接用 css 变量替换圆心或半径,因变量在值计算阶段未展开,浏览器无法解析为长度/位置;须用 calc() 将变量转为合法单位(如 calc(var(--cx) * 1%)),且注意兼容性与性能陷阱。

radial-gradient 里为什么不能直接用 CSS 变量替换圆心坐标或半径
因为 radial-gradient() 的参数解析发生在 CSS 值计算阶段,而 CSS 变量(--x)在该阶段仍为未展开的字符串,浏览器无法将其当作长度或位置值参与计算。比如写 radial-gradient(circle at var(--cx) var(--cy), red, blue),会直接报错或退化为默认 at center。
用 calc() + 自定义属性实现动态圆心和半径的可行路径
必须把变量“提前注入”到支持计算的上下文中,核心是:变量只用于 calc() 内部,且整个表达式最终产出一个合法的长度/百分比值。浏览器能解析 calc(var(--r) * 1px),但不能解析 at var(--pos)。
- 圆心位置只能用
at calc(...)形式,且两个维度需分别写:例如at calc(var(--cx, 50%) * 1%) calc(var(--cy, 50%) * 1%) - 半径推荐用像素单位 +
calc():如transparent calc(var(--radius, 80) * 1px),避免百分比在不同容器中缩放失衡 - 若需响应式半径,可用
vmax单位:如calc(var(--scale, 1) * 12vmax),比%更可控 - 注意 IE 和旧 Safari 不支持
calc()在radial-gradient位置参数中的使用,需降级 fallback
实际可运行的变量化 radial-gradient 示例
下面这段代码能在现代浏览器中正常工作,圆心和半径均可通过 JS 或 :root 修改:
body {
--cx: 50;
--cy: 50;
--radius: 100;
background: #eee;
background: radial-gradient(
circle at calc(var(--cx) * 1%) calc(var(--cy) * 1%),
#ff6b6b,
transparent calc(var(--radius) * 1px)
);
}
关键点:
-
calc(var(--cx) * 1%)把数字变量转成合法百分比值(50 → 50%) - 半径用
px而非%,防止窄屏下扩散消失、宽屏下糊满全屏 - 没写
at center的 fallback,是因为calc()失败时整条声明会被忽略,回退到上一行background: #eee
容易被忽略的兼容性与性能陷阱
看似灵活的变量方案,在真实项目里常踩三个坑:
- Firefox 对
calc()在radial-gradient中的支持较晚(91+),低于此版本会静默失效 - 用
filter: blur()模拟柔边时,配合变量更新会导致重绘开销激增,滚动卡顿明显 - 若将该渐变设在
body或全屏div上,且变量频繁变更(如鼠标跟随),务必加will-change: background,否则 Chrome 可能不触发图层提升
最稳妥的做法:圆心固定用 at center,只让半径响应式;或者用 JS 动态生成 style 标签,绕过 CSS 变量解析限制。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











