picture标签仅按顺序匹配首个满足条件的source,不裁图不计算;media必须写在source内且带括号,顺序须从宽到窄,img为必需fallback并含src与alt。

picture 标签本身不裁图、不缩放、不计算最优解,它只做一件事:从上到下扫描 <source></source>,遇到第一个匹配的就加载,然后停。写错顺序、漏括号、<img> 缺 src,都会导致你白写了所有 <source></source>,最终只加载那张 fallback 图。
为什么写了 media 却总加载同一张图
这不是浏览器不支持,而是匹配逻辑被破坏了,浏览器根本没走到你的规则里。
-
media写在<picture></picture>标签上(如<picture media="(max-width:768px)"></picture>)→ 浏览器完全忽略该属性 -
media="(max-width: 768px)"缺少外层括号 → 写成media="max-width: 768px"就静默失效 -
<source></source>放在<img>后面 → 所有<source></source>被跳过,只加载<img src> - 断点重叠,比如同时存在
(min-width: 768px)和(max-width: 768px)→ 768px 宽度行为不可控,不同浏览器可能结果不同
<source></source> 的顺序必须从宽到窄
浏览器不做“最优匹配”,只做“首个命中”。顺序错了,小屏设备永远拿不到手机图,宽屏设备永远卡在第一行。
- ✅ 正确(桌面 → 平板 → 手机):
<source media="(min-width: 1200px)" srcset="hero-desktop.jpg"></source>,<source media="(min-width: 768px)" srcset="hero-tablet.jpg"></source>,<source media="(max-width: 767px)" srcset="hero-mobile.jpg"></source> - ❌ 错误(手机规则放最前):
<source media="(max-width: 767px)" srcset="hero-mobile.jpg"></source>→ 所有 ≤767px 的设备都走这条,后面两条永不执行 - ⚠️ 断点建议用开区间:用
max-width: 767px+min-width: 768px+min-width: 1201px,避免边界冲突
<img> 不是可选装饰,是强制 fallback 节点
它承担三重角色:语义基础(屏幕阅读器只读它的 alt)、降级保障(IE 直接忽略整个 <picture></picture>)、兜底加载(所有 <source></source> 都不匹配时的最后防线)。
- 必须存在,且必须是完整闭合标签:
<img src="fallback.jpg" alt="首页横幅">—— 不能写成<img>或<img> - 漏掉
src或路径 404 → 整个图片区域空白,尤其在 Safari 16.4 之前版本中无任何提示 - 推荐给
<img>也加srcset和sizes,尤其当 fallback 图也要适配 2x 屏时
type 和 MIME 类型不一致会导致静默跳过
写 type="image/webp" 却返回 Content-Type: image/jpeg,Chrome 会标为 blocked:mime-type,Network 面板里能看到请求被拦住。
-
type值必须大小写、拼写、空格全对:image/webp✅,webp❌,image/jpg❌(正确是image/jpeg) - 服务器响应头
Content-Type必须与type严格一致,Nginx/Apache 需单独配置 WebP、AVIF 等类型 - WebP + JPEG 双格式回退时,建议结构为:
<source type="image/avif"></source>→<source type="image/webp"></source>→<source type="image/jpeg"></source>→<img>
真正麻烦的从来不是写几行 HTML,而是每张预裁图是否精准对应设计稿的构图意图、每个断点是否在真实设备上验证过、每条 type 是否和服务端 MIME 配置对齐——这些地方一漏,<picture></picture> 就退化成一个华丽的 <img> 容器。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











