<picture> 标签不提供切换动效,仅在加载时由浏览器依据 media、sizes、type 等属性一次选对资源;常见失效原因包括 media 写错位置、sizes 缺失或不匹配、type 与响应头不一致、主题变化不触发重选等。

<picture> 标签本身不实现“切换效果”,它只在加载阶段由浏览器选择一张最合适的图片资源——没有 JS 干预、没有过渡动画、不重复下载。所谓“流畅切换”,其实是避免布局抖动、防止回退到小图、确保高 DPR 设备拿到对应资源。关键不在视觉动效,而在配置是否让浏览器一次就选对。
为什么写了 media 却还是只显示 fallback 图
常见现象:页面加载后始终显示 <img src="fallback.jpg">,哪怕屏幕尺寸明显匹配某个 <source>。
-
media属性写在了<picture>标签上(无效),必须只写在<source>内部 - 语法错误:写成
media="max-width: 768px"(缺括号)→ 浏览器静默忽略整条<source> -
<source>放在<img>后面 → 浏览器直接跳过,不解析 - 所有
media条件都不满足(比如写了(min-width: 1200px)但当前视口只有 1199px)→ 自动 fallback 到<img>
sizes 必须写在 <img> 上,且要和 CSS 实际占位一致
如果你用 w 描述符(如 "photo-800w.jpg 800w"),sizes 就不是可选项,而是计算依据。浏览器靠它估算“这张图在页面中渲染多宽”,再结合设备 DPR 算出该加载哪个 w 值。
- 错误写法:
<source sizes="100vw">→sizes在<source>上被完全忽略 - 危险写法:
sizes="100vw"但实际 CSS 中图片容器是width: 50%;→ 小屏可能加载 1200w 图却只渲染 375px 宽,浪费带宽 - 推荐写法:
<img sizes="(min-width: 1200px) 1200px, (min-width: 768px) 768px, 100vw" ...>
WebP 优先 + JPEG 降级时,type 和服务端 Content-Type 必须匹配
浏览器看到 type="image/webp" 会尝试加载,但如果服务器返回的响应头是 Content-Type: image/jpeg,Chrome 会标记为 blocked:mime-type 并跳过,直接落到下一条 <source> 或 <img>。
立即学习“前端免费学习笔记(深入)”;
- 本地开发用
file://协议时,type声明基本失效(无服务端响应头) - 测试前务必用
curl -I https://yoursite.com/photo.webp检查真实响应头 - 不要把 WebP 放在
<img>的src里——<img>是兜底,应保持最大兼容性(JPEG/PNG)
节日换肤或深色模式切换,别指望 <picture> 自动响应变化
prefers-color-scheme 或自定义主题 class 变化时,<picture> 不会重新触发资源选择。浏览器只在初始加载时匹配一次。
- 方案一(推荐):预置多组
<picture>,用 CSS 控制显隐,如.theme-dark .pic-dark { display: block; } - 方案二:JS 监听
matchMedia("(prefers-color-scheme: dark)").addEventListener("change", ...),然后手动替换<img>的src和srcset - 切勿只改
src而忽略alt和loading="lazy",否则影响可访问性和性能
最容易被忽略的是:没有 <img> 就没有图;sizes 写错位置就白配;type 和响应头不一致就等于没写。这些点不出错,<picture> 才真正“流畅”——不是动效流畅,是选择一次到位。



















