filter: blur(var(--blur)) 失效是因为 blur() 函数不接受未注册变量,必须先用 @property --blur-radius { syntax: ''; initial-value: 0px; } 显式声明类型,否则浏览器将其当非法参数丢弃,devtools 中显示为 unset 或整行灰掉。

直接用 filter: blur(var(--blur)) 会失效,不是写法错,而是 CSS 语法限制 —— blur() 函数不接受未注册的变量。必须先用 @property 声明变量类型,否则浏览器跳过该声明。
为什么 filter: blur(var(--blur)) 不生效
浏览器解析 filter 时,对函数参数有严格校验:blur() 只接受带单位的长度值(如 4px),不接受裸变量。即使 --blur 已在 :root 中定义为 4px,未注册前仍被当作非法参数丢弃。DevTools 中常表现为 filter 行显示为 unset 或整行灰掉。
必须显式注册:
@property --blur-radius {
syntax: '<length>';
inherits: false;
initial-value: 0px;
}</length>
注册语句需放在 :root 或全局 <style></style> 块中,不能通过 JS 动态插入 <style></style> —— 部分浏览器(如 Safari)不识别运行时注入的 @property。
如何配合图片加载流程动态控制模糊强度
渐进式加载的核心是「先模糊占位 → 后清晰呈现」,变量控制要嵌入真实加载节奏,而非单纯切换数值。
- 初始状态设
--blur-radius: 6px,对应明显但不过度消耗性能的模糊 - 监听高清图
load事件后,用el.style.setProperty('--blur-radius', '0px')触发过渡 - 务必搭配
transition: filter 0.4s ease,且元素需为display: block(内联<img>在旧版 Safari 中过渡不稳定) - 避免在
display: none或visibility: hidden状态下修改变量 —— 动画不会回溯播放,得先show再set
注意:移动端 iOS WebKit 对 blur() > 8px 会自动降级为均值模糊(效果发虚),且不触发 transitionend,建议模糊上限设为 6px。
兼容性 fallback 怎么做才不翻车
Safari(截至 2026 年 4 月)和 Firefox 102 及更早版本不支持 @property,硬推变量动画会导致这些浏览器完全无模糊效果,甚至样式错乱。
安全做法是用预设类名 + JS 控制:
.blur-0 { filter: blur(0); }
.blur-2 { filter: blur(2px); }
.blur-6 { filter: blur(6px); }
JS 中根据加载阶段切换:
el.classList.replace('blur-2', 'blur-6');
关键约束:
- 不要混用类名和变量控制同一元素的
filter—— CSS 优先级易冲突,Safari 下可能类名被变量覆盖却无动画 - 降级方案必须用
@supports (filter: blur(1px))包裹,确保不支持filter的老浏览器彻底跳过 - 若同时用
backdrop-filter,需单独检查其支持性:@supports (backdrop-filter: blur(1px)),Edge 113 及更早版本会静默忽略
容易被忽略的性能与层级陷阱
即使变量注册正确、filter 值也生效,动画仍可能静默失败 —— 根本原因常是图层合成被意外打断。
-
filter动画依赖图层提升(layer promotion),若父容器有transform: translateZ(0)或will-change: transform,反而干扰 blur 图层创建 - 伪元素(如
::before)仍是推荐载体,避免影响内容层;变量定义在父容器上,子伪元素通过继承读取 - 变量值建议限定在
2px~6px:人眼对 0–4px 模糊变化最敏感,超过 6px 差异感知急剧下降,且渲染开销上升
真正难处理的不是“怎么动”,而是“什么时候动”——滚动中批量触发、视口判断不准、或 dpr 切换后缓存失效,都比变量本身更易导致体验断裂。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











