<img>是<picture>必需的fallback节点,必须存在且完整闭合(含src和alt),否则无匹配时图片区域空白;<source>需按从宽到窄顺序排列,media语法必须正确,否则浏览器静默跳过。

不写 <img> 标签,<picture> 就完全失效——它不是可选项,是语义、可访问性和降级的最后防线。
为什么 <img> 必须放在 <picture> 里且不能自闭合
浏览器解析 <picture> 时,会线性扫描所有 <source>,一旦匹配就停止;但如果没有找到任何匹配项,或所有 <source> 都因语法错误(如 media 写错、type 拼错)被跳过,它不会“自动 fallback”到 srcset 或默认图——它直接什么也不加载。
此时,<img src="fallback.jpg" alt="描述"> 是唯一能兜底的元素。漏掉 alt 不仅影响屏幕阅读器,旧版 Safari 还可能拒绝渲染该 <img>。
- 必须写成
<img src="..." alt="...">,不能是<img />或<img> -
src值应指向一个真实存在、兼容性极广的格式(如 JPEG 或 PNG),不能是 WebP/AVIF - 如果用构建工具生成多格式,确保 fallback 图在打包产物中确实存在且路径正确
<source> 的 media 顺序和断点怎么写才不白费
浏览器按从上到下的顺序检查每个 <source> 的 media,遇到第一个为 true 的就立即选用,不再往后看。顺序错了,所有设备都走第一条规则。
立即学习“前端免费学习笔记(深入)”;
常见错误:把手机规则 media="(max-width: 767px)" 放最前,结果桌面用户也加载了小图;或者断点重叠,比如同时写 (min-width: 768px) 和 (max-width: 768px),768px 宽度只命中前者。
- 正确顺序必须是从宽到窄:
min-width: 1200px→min-width: 768px→max-width: 767px - 断点值必须和 CSS 布局实际生效的断点一致,别凭空写 767px——如果栅格系统用的是 768px,
<source>就得用 768px -
media属性只能写在<source>上,写在<picture>标签上会被完全忽略
type 属性拼错或缺失导致现代格式完全不生效
<source type="image/webp"> 中的 type 是 MIME 类型校验,浏览器只加载自己支持且 type 声明匹配的 <source>。拼错一个字符(如 image/webp; 多个分号)、大小写错误(IMAGE/WEBP)、或漏写,整条 <source> 就静默跳过。
更隐蔽的问题是:某些 CDN 或静态服务器未正确配置 WebP 的 MIME 类型响应头,即使 HTML 写对了,浏览器收到 Content-Type: text/plain 也会拒收。
- 验证方式:打开 DevTools → Network → 点击图片请求 → 查看 Response Headers 中的
Content-Type - 不要依赖
type单独判断——media和type是 AND 关系,两个都满足才启用该<source> - WebP fallback 到 JPEG 是刚性需求,
<source type="image/jpeg">后必须紧跟一个不含type的<img>,否则无图
sizes 被忽略的三个高发原因
sizes 不是 CSS,它是纯字符串,浏览器靠它预估图片渲染宽度,再结合 srcset 中的 w 描述符选图。但它极易被忽略,导致浏览器退化为只加载 src。
- 漏写
sizes:只写srcset不写sizes,浏览器按默认 100vw 计算,小屏也下大图 - 混用单位:
srcset里同时出现480w和2x,整个srcset被丢弃 -
sizes值与真实布局脱节:比如图片在 flex 容器中占 1/3 宽,但sizes写死"100vw",浏览器选图逻辑彻底失准
真正麻烦的是:CSS 布局改了,sizes 没同步更新——这种问题上线后很难复现,只能靠定期比对 DevTools 的 Elements 和 Network 面板。



















