sizes 属性必须与 srcset 中的 w 描述符配合使用,否则浏览器无法匹配图片宽度而退化加载;它只能写在 img 标签上,需真实反映 CSS 渲染宽度,且媒体查询格式、单位缺一不可。

浏览器加载了最大图、移动端卡顿、图片模糊或撑破屏幕——这些问题几乎全出在 sizes 没写对,或者压根没配 sizes。只要用了 w 描述符(比如 400w),sizes 就不是可选项,而是强制搭档。
为什么写了 srcset 却还是只加载 src 或第一张图
根本原因:浏览器看到 srcset 里有 400w、800w 这类宽度描述符,就立刻进入「宽度匹配模式」,但它完全不知道这张图在页面里实际渲染多宽。没有 sizes,它无法把视口宽度 × DPR 和这些 w 值对上号,只能放弃整个 srcset,退化为加载 src 或第一个候选图。
常见错误现象:
-
srcset="a.jpg 400w, b.jpg 800w"但没写sizes→ Chrome/Firefox 通常只加载src;Safari iOS 11–12.0 可能完全不触发选择逻辑 -
sizes写成"50%"或"400"(缺单位)→ 整个属性被解析失败,srcset形同虚设 - 最后一项没写兜底,如
sizes="(max-width: 768px) 100vw"→ 旧版 Safari 或某些 Edge 会 fallback 到100vw,小屏也拉大图
sizes 必须真实反映 CSS 布局宽度,不是设计稿标注
sizes 不是控制样式,而是提前告诉浏览器“这张图将渲染成多宽”。它必须和你实际生效的 CSS 对齐,否则选图就偏了。
立即学习“前端免费学习笔记(深入)”;
实操建议:
- 别抄设计稿写的“768px 断点下显示 256px”,要打开 DevTools → Elements → 选中
img→ Computed 面板看width的实际像素值,再换算成vw或px - CSS 是
width: 100%; max-width: 400px;,那sizes就得写成"(max-width: 400px) 100vw, 400px" - 栅格三列(
grid-template-columns: repeat(3, 1fr)),间隙共 24px → 每列≈33vw,不是33.33vw(实测更稳) - 内联图标固定
24px × 24px→ 直接写sizes="24px",不用媒体查询
w 和 x 描述符绝对不能混用
srcset 解析时,浏览器靠后缀判断匹配逻辑:遇到 x 就看设备像素比(DPR),遇到 w 就结合 sizes 算目标物理像素宽度。混写会导致部分浏览器直接忽略整个 srcset,只加载 src。
典型错误写法:
-
srcset="small.jpg 1x, medium.jpg 480w, large.jpg 800w"→ 全部失效 -
srcset="icon-1x.png 1x, icon-2x.png 2x, icon-480w.png 480w"→ Safari、Firefox 直接跳过
正确做法:按场景二选一
- 适配不同分辨率(推荐):统一用
w描述符 +sizes - 只适配 DPR(简单场景):用
1x、2x,不写sizes,但仅限固定尺寸图(如 logo)
的 sizes 必须写在 img 上,source 上无效
很多人把 sizes 错误地写在 <source> 标签上,比如:
<picture> <source srcset="a.jpg" media="(min-width: 768px)" sizes="(min-width: 768px) 50vw"> <img src="b.jpg" alt=""> </picture>
这段代码里的 sizes="(min-width: 768px) 50vw" 完全不会被解析——sizes 只允许出现在 <img> 标签上,且必须和 srcset 同在该 img 中才起作用。
真正有效的写法是:
<picture> <source srcset="a.jpg" media="(min-width: 768px)"> <source srcset="b.jpg" media="(min-width: 480px)"> <img src="c.jpg" srcset="c-400w.jpg 400w, c-800w.jpg 800w" sizes="(max-width: 480px) 100vw, (max-width: 768px) 50vw, 33vw" alt=""> </picture>
注意:<img> 仍需承担兜底职责,同时承载响应式逻辑。
最常被忽略的一点:所有媒体查询中的空格必须规范,(max-width: 768px) 中冒号后必须有空格,写成 (max-width:768px) 会让旧版 Safari 和 Edge 整条规则失效;sizes 也不支持 calc() 或 CSS 变量,哪怕只是 var(--md) 也会让整条属性作废。



















