sizes属性仅在上生效,写在中完全无效;浏览器仅从读取sizes以计算布局宽度,缺失或错位将导致w描述符退化为100vw估算,引发大图加载。

picture里的不支持sizes属性,只有
上写才生效
很多人在sizes,比如<source sizes="(max-width: 768px) 100vw"></source>,这完全无效——浏览器直接忽略。所有sizes必须写在最外层的<img>上,这是规范强制要求,不是兼容性问题。
原因很简单:<source></source>只负责提供候选资源和匹配条件(如media或type),而图片最终渲染宽度由<img>的布局决定,浏览器只能从<img>读取sizes来计算“这张图该占多宽”。
- 写错位置会导致
srcset中w描述符退化为按100vw估算,小屏照样加载大图 -
<source></source>可以有自己的srcset,但它的选图逻辑只依赖media是否匹配,不参与sizes计算 - 如果
<img>没写sizes,哪怕<source></source>写了也没用
srcset用w描述符时,sizes必须覆盖所有media断点的实际渲染宽度
比如你用media="(max-width: 480px)"切小屏<source></source>,那对应的小屏场景下,<img>的sizes就得真实反映小屏时图片的盒模型宽度,不能笼统写"100vw"就完事。
常见错误是:CSS里给图片容器加了max-width: 320px,但sizes仍写"(max-width: 480px) 100vw",结果视口414px时浏览器算出需414px宽,却去srcset里找≥414w的图——如果最小只提供640w,就只能硬选它。
- 正确做法是让
sizes分支和<source></source>的media逻辑对齐,例如sizes="(max-width: 480px) 320px, (min-width: 481px) 600px" - 如果布局随横竖屏变化(比如
orientation: landscape时图片变宽),sizes也要显式加上对应分支 - 避免用
rem或%单位——浏览器只认vw、px、em等合法长度单位
多个的media顺序错了,sizes再准也没用
<picture></picture>从上到下匹配第一个满足media的<source></source>,后面的全跳过。所以顺序就是优先级。
典型翻车场景:把media="(min-width: 400px)"这种宽泛条件放在前面,后面更精确的media="(min-width: 1200px) and (orientation: landscape)"永远没机会执行——浏览器根本不会继续往下看。
- 把最具体、最高优先级的条件放最上面,比如
(min-width: 1440px) and (orientation: landscape) - 通用兜底条件(如
media="(min-width: 481px)")放最后,但必须确保它能覆盖所有未被前面匹配的情况 - 每个
<source></source>的srcset应只包含该断点下真正需要的尺寸,别一股脑塞进所有分辨率
验证是否真生效,只看Network里实际请求的URL
别信“看起来清晰”,也别靠DevTools里Elements面板看srcset有没有渲染出来——那只是HTML字符串。关键看浏览器到底发了哪个请求。
必须关掉缓存再测:Chrome无痕窗口 + DevTools → Network → 勾选Disable cache → 切设备模拟器(如iPhone SE)→ 刷新页面 → 找到img请求,看Name列加载的是hero-400w.jpg还是hero-1920w.jpg。
- 如果始终只加载
<img>的src值,先检查控制台有没有Failed to parse 'srcset'报错 - 如果
srcset里混用了400w和2x,整个srcset会被浏览器静默丢弃,直接 fallback 到src - 移动端横屏切换后,
sizes不会自动更新——得用JS监听resize或orientationchange手动重设
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr))这类动态布局时,图片实际宽度在不同视口下可能落在两个断点之间,sizes若只写固定像素值(如300px),就无法覆盖这种浮动宽度,必须配合vw或用JavaScript动态计算。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











