Lightning CSS 去重导致 backdrop-filter 在生产环境失效
现象
本地开发一切正常,铺满磨砂玻璃质感。部署到 Cloudflare Workers 之后,所有毛玻璃面板——首页的 UPageCard、CommandPalette、Drawer——全部变成纯透明,背景虚化效果完全消失。
DevTools 确认居然是 backdrop-filter: none。
排查过程
首先怀疑是不是 Cloudflare Workers 环境差异,试了 Curl、Rocket Loader、各种 header——都不是。
用 Playwright 启动 Chrome 无头浏览器直接对比 Dev 和生产构建产物的计算样式:
- Dev:
backdropFilter: "blur(24px) saturate(1.35) contrast(1.05) brightness(1.04)"✅ - Prod:
backdropFilter: "none"❌
关键一步是用 Playwright 创建隔离测试——只通过 inline style 测试 Chrome 对 backdrop-filter 和 -webkit-backdrop-filter 的支持情况:
| inline style | 计算值 |
|---|---|
backdrop-filter: blur(1.5rem) | blur(24px) saturate(1.35) ✅ |
-webkit-backdrop-filter: blur(1.5rem) | none ❌ |
Chrome 根本不认 -webkit-backdrop-filter。 那生产 CSS 里是什么情况?
看一眼生产构建的 CSS 产物:
/* 源码 */
.glass-surface {
backdrop-filter: blur(1.5rem) saturate(1.35) contrast(1.05) brightness(1.04);
-webkit-backdrop-filter: blur(1.5rem) saturate(1.35) contrast(1.05)
brightness(1.04);
}
/* Lightning CSS 压缩后 */
.glass-surface {
-webkit-backdrop-filter: blur(1.5rem) saturate(1.35) contrast(1.05)
brightness(1.04);
}
unprefixed 的 backdrop-filter 被完全丢弃了,只留下了 Chrome 不认的 -webkit-backdrop-filter。
根因
Nuxt 生产构建使用 Lightning CSS 做 CSS 压缩。Lightning CSS 在处理同时存在的 backdrop-filter 和 -webkit-backdrop-filter 时,会做 dedup:保留后声明的那个,丢弃另一个。
源码顺序:backdrop-filter 在前 → -webkit-backdrop-filter 在后 → Lightning CSS 保留 -webkit-backdrop-filter,丢弃 backdrop-filter。
但 Chrome 不识别 -webkit-backdrop-filter(它是早期的 WebKit 专有前缀,Chromium 早已转向标准属性),导致计算值为 none。
对应 Lightning CSS Issue:
修复
把声明顺序颠倒——让 -webkit-backdrop-filter 在前,backdrop-filter 在后:
.glass-surface {
-webkit-backdrop-filter: blur(1.5rem) saturate(1.35) contrast(1.05)
brightness(1.04);
backdrop-filter: blur(1.5rem) saturate(1.35) contrast(1.05) brightness(1.04);
}
改为把 -webkit- 放前面、unprefixed 放后面后,构建产物中 两个声明都被完整保留,实际输出如下:
.glass-surface {
-webkit-backdrop-filter: blur(1.5rem) saturate(1.35) contrast(1.05)
brightness(1.04);
backdrop-filter: blur(1.5rem) saturate(1.35) contrast(1.05) brightness(1.04);
}
Chrome 忽略 -webkit- 版本,使用 unprefixed 版本,计算值恢复正常。
涉及本项目的 5 处修改(app/assets/css/main.css):.glass-surface、.glass-header、.glass-control、.gallery-card-copy、.glass-menu-item::before。
总结
Lightning CSS 在做 prefix dedup 时,对 backdrop-filter 的处理存在一个已知问题——当同时存在 backdrop-filter 和 -webkit-backdrop-filter 时,会丢弃其中一个。现代浏览器(Chrome / Edge)不认 -webkit- 前缀,导致属性完全失效。
目前的 workaround 很简单:-webkit- 声明放在 unprefixed 声明之前,确保两个版本都被保留。Chrome 使用 unprefixed 版本,Safari 使用 -webkit- 版本,互不干扰。
