<picture>标签本身不裁切图片,仅按<source>的media、type及<img>的srcset/sizes选择预裁剪源图;media须写在<source>内、带括号、从宽到窄排序,否则静默失效或只加载fallback。

<source> 的 media、type 和最外层 <img> 的 srcset/sizes 做的资源选择决策。
为什么写了 media 却总加载同一张图
这不是浏览器不支持 <picture>,而是匹配逻辑被悄悄绕过了:
-
media属性写在<picture>标签上(如<picture media="(max-width: 768px)">)→ 浏览器完全忽略 -
media="(max-width: 768px)"写成media="max-width: 768px"(漏括号)→ 静默失效,该<source>被跳过 -
<source>放在<img>后面 → 浏览器不扫描,直接 fallback 到<img src> - 所有
<source>的media都不匹配(比如断点留了缝隙:768px 宽度没被任何规则覆盖)→ 浏览器不报错,默默加载<img src>
source 的顺序不是可选的,是匹配逻辑本身
浏览器从上到下线性扫描 <source>,遇到第一个 media 为 true 的就停止,后续全部丢弃。这不是“多选”,是短路判断:
- ✅ 正确(宽屏优先):
<source media="(min-width: 1200px)" srcset="desktop.jpg">→<source media="(min-width: 768px)" srcset="tablet.jpg">→<source media="(max-width: 767px)" srcset="mobile.jpg"> - ❌ 错误(窄屏放最前):
<source media="(max-width: 767px)" srcset="mobile.jpg">→ 所有设备都卡在这条,后面两条永不执行 - ⚠️ 断点重叠(如
(min-width: 768px)和(max-width: 768px))→ 768px 视口行为不可控,Chrome 和 Safari 可能给出不同结果
srcset 和 sizes 不是“可有可无”的优化项
仅靠 media 只能切固定断点图;若还要适配高 DPR 或视口缩放,必须靠 <img> 上的 srcset + sizes:
-
sizes只能写在<img>上,写在<source>里会被完全忽略 -
sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 33vw"告诉浏览器“这张图在页面中实际占多宽”,它和srcset中的w描述符配合计算——省略sizes会导致浏览器按默认100vw估算,小屏也可能加载桌面尺寸图 -
<source>的srcset里写2x是无效的,DPR 适配只能由最外层<img>的srcset处理 - 混用
w和x(如"a-400w.jpg 400w, b@2x.jpg 2x")会让整个srcset值被解析为无效,回退到src
type 属性失效往往不是代码问题,而是服务器配置
<source type="image/webp"> 匹配失败,90% 情况下不是 HTML 写错了,而是服务端没返回正确的响应头:
立即学习“前端免费学习笔记(深入)”;
- 服务器必须返回
Content-Type: image/webp,大小写、拼写、空格全要一致 -
type="webp"或type="image/jpg"是非法值,浏览器静默丢弃整条<source> - Network 面板看到
blocked:mime-type或状态码为 404,基本可以确定是 MIME 类型和服务端文件类型不匹配 - 推荐三层 fallback:
<source type="image/avif">→<source type="image/webp">→<img src="fallback.jpg">
<picture> 就会安静地退回到 <img src>,你甚至看不到任何警告。



















