图片加载前用透明背景容器+absolute定位::after伪元素实现毛玻璃占位,加载完成通过.complete属性与load事件双保险触发.loaded类切换,配合@supports检测backdrop-filter兼容性并降级。

图片加载前用 ::after 占位并模拟毛玻璃效果
直接给图片加 backdrop-filter: blur(10px) 没用——它只对「背后」的元素起作用,而图片本身是前景内容。真正可行的做法是:让容器保持透明背景,用 ::after 伪元素盖在图片上方,同时让它「透出底下模糊的页面内容」,形成毛玻璃感。
关键点在于:::after 必须设为 position: absolute、inset: 0,且父容器需有 position: relative 和 background: transparent(不能是纯白或实色)。
- 父容器若设了
background: #fff,::after再怎么模糊也只糊到白色,毫无毛玻璃感 -
::after的background必须是transparent,否则会遮死底层 - 模糊值建议从
blur(4px)起调,太大容易丢失轮廓,太小不明显
图片加载完成时移除 ::after 并触发淡入
不能依赖 img.onload 手动删 class——现代浏览器中,loading="lazy" 或缓存命中会让图片异步加载时机不可控;更可靠的是用 img 元素的 complete 属性 + load 事件双保险。
CSS 侧只需定义两套状态:默认显示伪元素 + 模糊,加类名(如 .loaded)后隐藏它,并用 opacity 过渡图片本身:
img {
opacity: 0;
transition: opacity 0.3s ease;
}
img.loaded {
opacity: 1;
}
.container::after {
content: "";
position: absolute;
inset: 0;
background: transparent;
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
}
.container.loaded::after {
display: none;
}
- 务必加
-webkit-backdrop-filter,Safari 旧版只认这个 - 不要对
::after做 opacity 动画——它本身没内容,渐隐会显得“突然消失”,不如直接display: none - 图片
opacity过渡时间建议 ≤ 0.35s,太久会让人觉得卡顿
兼容性与性能陷阱:哪些设备根本跑不动 backdrop-filter
backdrop-filter 在 iOS Safari 9+、Chrome 76+、Edge 79+ 才稳定支持;但即使支持,低端 Android 或旧 iPad 上一开就掉帧——不是 CSS 写错了,是渲染管线扛不住实时高斯模糊。
上线前必须做真机验证,尤其检查滚动中是否卡顿。稳妥方案是加一层检测:
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
.container::after {
/* 启用毛玻璃 */
}
}
- 别用 JavaScript 检测
backdrop-filter支持——CSS @supports 更准,且能被 SSR 正确处理 - 如果目标用户含大量微信内置浏览器(X5 内核),基本可放弃:X5 完全不支持
backdrop-filter,连@supports都会误判 - 模糊半径超过
12px在部分安卓机上会触发降级为纯色块,而非模糊
毛玻璃渐现看着轻巧,实际卡点全在「什么时候关伪元素」「谁来负责过渡」「不支持时怎么降级」这三件事上。最常被忽略的是:父容器背景必须透出真实页面内容,而不是靠伪元素自己画一层灰色再模糊——那只是假毛玻璃。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











