sizes="auto":让布局给出宽度
w 描述符与 sizes §3 的结论是:sizes 是一份手抄的 CSS,它存在只是因为浏览器必须在布局之前选图。这条约束对懒加载的图不成立。loading="lazy" 的图要等进入视口附近才开始下载,那时样式与布局早已就绪,图片有多宽是一个现成的答案。sizes="auto"
就是把这个答案接进选择算法。
1 · 生效条件
规范把条件写成一个谓词:当且仅当 loading 处于 Lazy 状态,且 sizes 的值是 auto 或以 auto, 开头(均不区分大小写)时,这个 <img> 才 allows auto-sizes。满足时,auto 取图片的 concrete object size 的宽度(CSS
像素);不满足时,auto 被忽略,继续求值后面的项。
<img loading="lazy" sizes="auto"
srcset="photo-320.jpg 320w, photo-640.jpg 640w, photo-1280.jpg 1280w"
width="1280" height="853" alt="…">
有两处容易误读。其一,loading="lazy" 本身不会让缺省的 sizes 变成 auto:实测 Chrome 154 里只写 loading="lazy" 不写 sizes,视口 1440px 下仍按 100vw 选中 1920w。2019 年的原始提案曾设想「懒加载时省略
sizes 即为 auto」,最终合入的规范只在 <picture> 的 <source> 上保留了这个省略:<img> 满足条件时,它前面兄弟 <source> 的 sizes 可以不写,等同于 auto。其二,auto
只能出现在列表开头,写成 (min-width: 600px) auto 或放在中间都不合法(核对于 2026-09)。
旧浏览器不认识 auto,按 sizes 的解析规则把它当作一个无效项跳过,于是可以在其后给出回退:
<img loading="lazy"
sizes="auto, (min-width: 1000px) 300px, calc(100vw - 32px)" …>
支持 auto 的浏览器取布局宽度,其后各项不再看;不支持的浏览器从第二项起照旧求值。Chrome 126(2024-06)、Firefox 150(2026-04)与 Safari 27(2026-09)先后支持(兼容性据 MDN BCD,核对于 2026-09),回退列表在存量设备淘汰之前仍有意义。
2 · 随附的 UA 样式
规范在 Rendering 一章为这个特性加了一条 UA 样式:
img:is([sizes="auto" i], [sizes^="auto," i]) {
contain: size !important;
contain-intrinsic-size: 300px 150px;
}
contain: size 让图片的尺寸不再依赖其内容,下载前后盒子都不会因图片本身而变化。规范没有写明这条样式的理由,作者的推断是它切断了一个潜在的循环:图片按布局宽度选定,加载后自身尺寸改变布局,布局改变又触发重新选择。代价是图片自身的宽高比也被一并隔离:盒子尺寸改由
contain-intrinsic-size 给出,即 300 × 150。
这条样式对本页最重要的实测结论是:只给 CSS 宽度不够。width: 300px、height: auto 的图,内容区高度读回 150px 而不是按 3:2 应有的 200px,图片被压扁;把宽度改为 150px,高度仍是 150px。height: auto 救不回来,因为它要找的天然宽高比已经被 contain: size 抹掉。补上
width / height 属性或 CSS aspect-ratio 之后,高度恢复为 100px(150px 宽时),这正是 尺寸与占位 一页推荐始终写宽高属性的另一个理由。
选择器只看 sizes 属性,不看 loading。loading="eager" 配 sizes="auto" 的图同样拿到 contain: size,同样被压成 150px 高,却享受不到 auto 的选图,两头落空。
sizes 与 loading 各取值组合下的选择结果与盒尺寸。可切换高度来源观察 contain: size 抹掉宽高比,调 padding 观察 auto 只取内容区宽度,切到 eager 观察 auto 的回退方式。3 · 取的是哪个宽度
规范文本说 auto 取 concrete object size 的宽度。这个量来自 CSS Images 的对象尺寸协商,在多数情况下等于内容区宽度,padding 与边框不计入。实测给 300px 宽的图加上左右各 100px 的 padding,边框盒 500px,选中的仍是按 300px 算的 320w。
object-fit: contain 暴露了两者的差别,2026 年 3 月提出的 whatwg/html#12248 讨论的就是这种情形。容器 1000 × 100、图片铺满容器且 object-fit: contain 时,图片加载前没有天然宽高比,concrete object size 就是 1000 × 100,选中大图;加载后若图片是正方形,concrete object size 缩成 100 ×
100,按规范文本应当再选一次小图。若小图的宽高比又与大图不同,这个过程甚至可能不收敛。
实测 Chrome 154 没有二次选择。图 3-1 在 760 × 80 的容器里放正方形候选,图面实际只占 80 × 80,currentSrc 在 1.4 秒内始终停在 960w——它按容器的内容区宽度选图,与 issue 里对 Blink 源码的描述一致。这对流量不友好:80px 的图面下载了 960px 的位图。对 object-fit: contain 的缩略图,auto
不如手写 sizes(核对于 2026-09)。
object-fit 三种取值下的 currentSrc 轨迹。可调容器宽与 object-fit,观察浏览器只按容器宽度选一次,不随图面缩小换图。4 · eager 图上的 auto
按规范现行文本,eager 图不满足 allows auto-sizes,auto 被忽略,求值继续到下一项;sizes="auto, 10px" 应当按 10px 选图。实测 Chrome 154 不是这样:eager 的 sizes="auto, 10px" 在视口 1440px 下选中 1920w,等价于把整个属性当作 100vw,后面的
10px 没有生效(核对于 2026-09)。
规范在这一点上改过一次。最初合入的文本让 eager 图上的 auto 等于 100vw;2023 年的 whatwg/html#9648 把它改成「忽略、取下一项」,起因是 WordPress 一类平台希望统一在 sizes 前面加上 auto,再按位置动态决定是否写 loading="lazy",这要求
eager 图上的 auto, 200px 落到 200px。2024 年 1 月的 whatwg/html#10110 报告 Chrome 里 sizes="auto, 200px" 的 eager 图「总是按 100vw 计算」,规范编辑在回复中指出规范已按 #9648 改为取下一项。本页的实测说明 Chrome 154
仍停在改动之前的行为。两者对齐之前,作者能依赖的规则很简单:sizes="auto" 只写在懒加载的图上,eager 图照旧手写 sizes(核对于 2026-09)。
警示 · 首屏主图不应写 loading="lazy",因而也用不上 auto。懒加载的图要等布局完成、进入视口附近才开始请求,首屏主图因此失去 preload scanner 提前发现的机会,LCP 会明显推迟。sizes="auto" 解决的是屏外图片的
sizes 手抄问题,首屏图片的 sizes 仍要手写。