blur-sm等类必须与filter类共用才生效,因filter是开启CSS filter属性的开关,blur-sm仅提供参数值;单独使用无效。

blur() 滤镜在 Tailwind 中的写法与生效前提
直接写 blur-sm 或 blur-md 不会自动让图片变模糊占位——前提是图片本身得是「加载中」或「未完成渲染」的状态。Tailwind 的 blur- 工具类只是设置 CSS filter: blur(),它不感知图片是否加载完成,也不会自动切换。真正常见的模糊占位效果,其实是靠「两张图叠加 + 透明度/模糊过渡」实现的:一张低质量占位图(LQIP)或纯色背景加 blur-md,另一张高清图加载完成后淡入并移除模糊。
关键点:
-
blur-类必须作用在容器或<img>元素上,且不能被transform、will-change等属性意外禁用硬件加速(否则模糊动画卡顿) - 若图片是通过
background-image加载的,需确保父容器有明确宽高,否则blur-可能不可见 - Blur 值越大(如
blur-xl),越消耗性能,移动端慎用超过blur-md
用 loading="lazy" + onload 触发模糊移除
最轻量、无需额外 JS 库的方案:利用原生 img 的 onload 事件,在高清图加载完成后移除模糊类。注意不能只靠 CSS :has(:loaded)(目前仅 Safari 支持),得靠 JS 控制 class 切换。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 初始状态给
<img>加上class="blur-md transition-all duration-500" - 加上
onload="this.classList.remove('blur-md')"—— 简单直接,无依赖 - 为防加载失败,可补充
onerror="this.classList.add('opacity-70')"降级显示 - 如果用 React/Vue,别在
useEffect或mounted里手动监听load,优先用原生onload,更可靠
配合 object-fit 和宽高约束避免布局偏移
模糊占位时若图片尺寸未固定,加载后容易引起页面抖动(layout shift)。Tailwind 本身不提供「占位宽高」工具类,必须显式约束。
推荐组合:
- 用
aspect-w-16 aspect-h-9(或自定义aspect-square)设定宽高比 - 加
object-cover或object-contain控制裁剪方式,否则blur会糊掉不该糊的边缘 - 避免只写
w-full h-full而不设父容器尺寸——模糊图会塌缩成 0×0 - 若服务端能生成 20px 宽的 LQIP base64 图,可设为
src初始值,再用data-src存真实地址,JS 加载后替换
transition 过渡失效的三个常见原因
写了 transition-all duration-300 却没动画?大概率卡在这几个地方:
-
blur属性本身不是 CSS 动画「可插值属性」,但现代浏览器已支持平滑过渡;若失效,检查是否同时用了filter: contrast(1.2)等其他 filter —— 多个 filter 需写成一行,如filter: blur(4px) contrast(1.2),否则浏览器可能丢弃部分值 - 元素初始没有
blur类,而是靠 JS 动态添加,但添加瞬间就触发了load,导致过渡来不及开始。解决:加setTimeout(() => img.classList.add('blur-md'), 10)延迟添加 - 父元素有
overflow: hidden且模糊半径超出边界,视觉上像“没动”,实际 blur 在运算。可临时加outline: 1px solid red查看真实渲染范围
模糊占位真正难的不是写几行 class,而是控制加载节奏、尺寸锚点和 filter 组合的边界条件——这些地方一松,用户体验就断层。


















