直接用filter: blur(var(--blur))失效,因CSS语法限制blur()函数不接受未注册变量;须先用@property注册--blur-radius为可动画长度类型,否则浏览器跳过该声明。

为什么直接用 filter: blur(var(--blur)) 会失效
这不是写法错,而是 CSS 语法限制:blur() 函数不接受变量作为参数值,除非该变量被 @property 显式注册为可动画类型。浏览器看到 blur(var(--blur)) 时,会当作无效声明跳过,最终 fallback 到无模糊效果。
常见错误现象:filter 值在开发者工具里显示为 unset 或直接消失;模糊没变化,但变量本身能读取到。
- 必须先注册变量:
@property --blur-radius { syntax: ''; inherits: false; initial-value: 0px; } - 注册后才能在
filter: blur(var(--blur-radius))中参与过渡 - 注册语句需放在 :root 或全局 style 块中,不能动态插入(否则部分浏览器不识别)
transition: filter 不触发动画?检查这三点
即使变量注册正确、filter 值也生效,动画仍可能静默失败。核心原因不是代码写错,而是浏览器对 filter 的合成策略被意外打断。
-
filter动画依赖图层提升(layer promotion),若父容器有transform: translateZ(0)或will-change: transform,反而可能干扰 blur 图层创建 - 元素若处于
display: none或visibility: hidden状态下修改变量,动画不会回溯播放——得先 show 再 set - 移动端 iOS WebKit 对大于
8px的blur()会自动降级为均值模糊(效果发虚),且不触发transitionend
兼容性降级:Safari 和旧版 Firefox 怎么办
Safari 目前(截至 2026 年 4 月)仍不支持 @property,Firefox 102 及更早版本也不支持。硬推变量动画会导致这些浏览器完全无模糊效果,甚至样式错乱。
安全做法是用预设类名 + JS 控制,而非强依赖变量动画:
- 定义降级类:
.blur-0 { filter: blur(0); } .blur-2 { filter: blur(2px); } .blur-6 { filter: blur(6px); } - JS 中根据加载阶段切换:
el.classList.replace('blur-2', 'blur-6') - 配合
transition: filter 0.3s ease,所有支持filter的浏览器都能动起来
注意:不要混用类名和变量控制同一元素的 filter,CSS 优先级容易冲突,导致 Safari 下类名被变量覆盖却无动画。
加载过程中动态调整模糊强度的合理节奏
渐进式模糊不是“越快越清晰”就好。人眼对模糊变化的敏感区间集中在 0–4px,超过 6px 后差异感知急剧下降,反而增加渲染开销。
- 推荐三阶节奏:
blur(8px) → blur(3px) → blur(0),每阶间隔 300ms 左右 - 首帧用高模糊(8px)快速占位,避免白屏或布局抖动
- 第二阶降到 3px 是关键过渡点,此时内容结构已可辨识,用户心理等待感大幅降低
- 最后一阶清零前,确保资源真正就绪(比如图片
onload触发,而非仅 DOM 插入)
容易被忽略的是:如果模糊过程和内容尺寸变化(如图片加载后撑开容器)同时发生,会引发 layout + paint 双重重绘。建议给容器设固定宽高,或用 aspect-ratio 预留空间。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











