先记住这个答案
宽度型 srcset 描述的是候选文件本身的像素宽度,sizes 描述图片预计在布局中占多少 CSS 像素。浏览器据此结合设备像素密度选择下载哪个文件,而真正的显示宽度仍由 CSS 决定。若 sizes 错报为 100vw,但图片实际只占侧栏,浏览器可能下载过大的资源。
srcset的w是源图宽度sizes描述预计 CSS 显示宽度- 实际显示宽度仍由 CSS 决定
- 浏览器决定最终候选
新闻卡片在两种布局中的显示宽度
新闻列表手机上图片占满卡片,桌面三列卡片每张约占视口三分之一。给图片提供 400、800、1200 像素宽的资源,在 sizes 中声明窄屏用 100vw、宽屏约 33vw。浏览器在下载前可据此选择合适资源;如果漏写 sizes,宽度描述符场景会按默认显示宽度估计,可能下载比实际所需更大的图。实际 CSS 列宽、间距也要与声明尽量一致。
<img
src="/card-800.jpg"
srcset="/card-400.jpg 400w, /card-800.jpg 800w, /card-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, 33vw"
alt="作者正在演示产品原型"
width="800" height="600">浏览器先读取 sizes 中第一个匹配的媒体条件,得到预计渲染显示宽度;再把 CSS 像素宽度与像素密度等因素结合,挑选合适的 srcset 候选。
示例里的 sizes="(max-width: 600px) 100vw, 33vw" 是估计:窄屏占满视口,宽屏约占三分之一。若页面两侧还有间距,实际宽度比 100vw 小;写得过大可能浪费资源,写得过小可能在高密度屏上发糊。用浏览器开发工具核对元素实际 CSS 宽度与最终 currentSrc,再调整 sizes,比只按设计稿宽度填写更稳。
浏览器按显示宽度与密度挑候选
候选选择由浏览器决定,不保证总是严格挑到数学上最近的文件;缓存和网络策略也可能参与。宽度描述符要写资源固有宽度,不能把显示宽度冒充为源宽度。width 和 height 属性还可提供宽高比,减少图片加载时的布局跳动。
假设桌面卡片实际宽 320 CSS 像素,屏幕密度为 2,浏览器大致需要约 640 像素宽的文件;若 sizes 却声称它占满 1200px 视口,就可能选到远大于需要的资源。缩放窗口时看 Network 中实际下载的候选,还要记住浏览器缓存可能让第二次测试看起来没有重新选图。sizes 描述布局估计,不负责把图片本身画成那个宽度。
容易答错的地方
- 把
sizes当作图片实际 CSS 宽度 - 它是选资源的显示宽度提示,真实布局宽度仍由 CSS 决定。
- 在
400w写的是显示宽度 400w表示该候选文件的固有像素宽度,应与资源本身一致。
面试官还会怎么问?
只有密度不同的同图,能用 1x、2x 吗?
可以。密度描述符适合同一显示尺寸下的不同清晰度候选。
为什么浏览器没选最小的图?
它还考虑预期显示宽度、设备密度、缓存等条件,不只比较文件列表顺序。
sizes 顺序重要吗?
重要。浏览器采用第一个匹配的条件,因此更具体的窄屏条件应放在前面,最后给默认显示宽度。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。