sizes单独写没用,因为它仅告知浏览器图像在当前视口下的渲染宽度,不触发媒体判断;真正控制“选用哪组图”的是<source>标签中的media属性,sizes则负责在该组内选择最匹配分辨率的候选图。

为什么sizes单独写没用,必须和media配合?
sizes本身不触发任何媒体判断,它只是告诉浏览器“这张图在当前视口下大概占多宽”。真正决定“用哪组图”的是 media 属性——它在 <source> 里生效,不是在 <img> 上。漏掉 media,浏览器就只能从 srcset 里硬挑一张,哪怕你写了 sizes="(max-width: 480px) 100vw, 50vw",它也看不到这个逻辑。
-
media控制“选哪一组源”(比如桌面横幅 vs 手机竖构图),sizes控制“这组里挑哪个分辨率” - 一个
<source>可以同时带media和srcset,但sizes必须写在最终的<img>标签上 - 如果只用
<img>+srcset+sizes,那media就完全用不上——这时你靠的是单一构图下的宽度自适应,不涉及艺术方向切换
media + sizes 组合怎么避免小屏加载大图?
典型错误是:写了 media="(min-width: 768px)",但 sizes 还按全屏算,比如 sizes="100vw"。结果 iPad 在 768px 宽度下命中了该 <source>,但浏览器看到 sizes="100vw" 就去选接近 768w 的图,哪怕这张图实际只显示在 300px 宽的卡片里。
- 每个
<source>对应的sizes值,要匹配它所覆盖的布局场景——比如手机端卡片图,sizes="(max-width: 480px) 90vw"比100vw更准 - 桌面端若图片固定宽 400px,
sizes="400px"比50vw更可靠;别依赖“大概差不多” - 检查 Network 面板里图片请求的
Sec-CH-DPR和Width请求头,没有说明sizes没生效或语法错(比如漏单位、逗号错位)
如何验证 sizes + media 是否真省了流量?
不能只看 HTML 写得对不对,得看浏览器实际加载了哪张图。DevTools 的 Network 面板是最直接证据,尤其注意“Size”列和“Type”列是否匹配你预设的断点。
- 在 iPhone 模拟器下刷新,看加载的是
768w.jpg还是1920w.jpg;如果是后者,要么media没拦住,要么sizes报告了错误宽度 - 用 “Throttling” 切换 Slow 3G,观察首屏图片是否仍能快速出现——如果卡顿,可能是
loading="lazy"和sizes冲突(懒加载会推迟计算,导致初始sizes误判) - 别信 Lighthouse 的“响应式图片建议”,它只静态扫描
srcset,不跑真实渲染逻辑
容易被忽略的兼容性细节
media 和 sizes 都是现代浏览器原生支持,但行为差异藏在细节里。比如 Safari 对 sizes 中嵌套媒体查询的支持比 Chrome 更严格,少个空格就可能回退到 100vw。
立即学习“前端免费学习笔记(深入)”;
-
sizes里的单位不能省:sizes="50vw"合法,sizes="50"直接失效 -
media查询不要写成max-device-width——这是过时写法,现代浏览器只认max-width(基于视口,非设备) - 所有
<source>必须放在<img>前面,顺序错了浏览器会跳过匹配
srcset,而在让每张图的 sizes 精确反映它在当前 media 条件下的真实渲染宽度。错一点,浏览器就可能多下 2MB。



















