真正起作用的是srcset+sizes或<picture>,二者必须协同生效;仅加max-width:100%不减少加载体积,浏览器无sizes时按100vw fallback,混用w/x描述符会导致整个srcset被忽略。

只加 max-width: 100% 不算响应式图片重构,它不减少加载体积,手机照样下 2000w 的图——真正起作用的是 srcset + sizes 或 <picture>,且二者必须协同生效。
为什么 srcset 单独写基本无效
浏览器看到 srcset 但没 sizes,就按默认规则 fallback 到 100vw,结果小屏仍加载大图;漏掉 sizes、混用 w 和 x 描述符(比如 "small.jpg 480w, big.jpg 2x"),整个 srcset 会被忽略,退化为只加载 src。
-
srcset必须统一用w(推荐)或统一用x,不能混 -
sizes是字符串,不是 CSS,不支持calc(),但支持媒体查询语法:"(max-width: 768px) 100vw, 50vw" - 如果图片在栅格中占 1/3 宽,且断点从 768px 开始,
sizes就该是"(max-width: 768px) 100vw, 33.33vw",不是硬写"100vw" - 旧版 Edge(EdgeHTML)对空格敏感:
"(max-width: 768px)"会失效,得写成"(max-width:768px)"
sizes 写错的典型表现
常见错误是把 sizes 当作“最大宽度”来写,导致桌面端加载小图、移动端反而出大图。比如父容器有 max-width: 600px,但 sizes="100vw" → 桌面端仍尝试加载 1920w 图;CSS 里写了 @media (min-width: 1200px) { width: 33vw; },但 sizes 漏掉这条规则 → 浏览器 fallback 到默认值,选错资源。
- 用了
rem布局,但sizes直接写"30rem"→ 浏览器不认识rem,当作无效值处理 - Flex 容器未设
min-width: 0,图片卡住不缩,max-width: 100%失效 -
sizes必须和真实 CSS 布局断点严格一致,比如用768px就别写成767px
什么情况下非用 <picture> 不可
<picture> 不是 <img> 的升级版,它是为两类明确需求设计的:美术裁剪(art direction)和格式降级(format fallback)。仅适配分辨率差异,srcset+sizes 更轻量。
立即学习“前端免费学习笔记(深入)”;
- 需要不同构图:手机裁人脸、桌面展全景 → 必须用
<source media="(max-width: 600px)" srcset="portrait.jpg"> - 需强制指定格式并提供降级路径:优先
type="image/avif",不支持就跳type="image/webp",最后 fallback 到<img src="fallback.jpg"> -
<source>的media和type是 AND 关系,顺序决定匹配优先级,最具体规则放最前 -
<img>必须放在<picture>最末尾,且带src和alt,否则不渲染
重构时最容易被忽略的兼容性细节
这些不是“写了就跑通”的事:Safari 12.1 之前对 w 描述符支持不全,旧 iOS 可能只按 DPR 粗略匹配;object-fit 在容器无明确宽高时完全不生效;flex 容器里 img 默认 min-width: auto 会卡住收缩,必须显式加 min-width: 0;sizes 值若与真实布局脱节,哪怕只差 1px,浏览器也可能选错资源。



















