HTML 响应式图片(img / picture)规范(工程版)

December, 23rd 2025 4 min read Markdown
HTML 响应式图片规范:img/picture + srcset 完整指南

本规范用于指导在真实项目中,如何正确、可维护、可审查地使用 <img> / <picture> + srcset + sizes,以达到:

  • 正确选图
  • 避免浪费流量
  • 保证清晰度
  • 行为可预测

一、核心原则(必须理解)

原则 1:浏览器不会“猜布局”

浏览器不会根据 DOM / CSS / 容器实际宽度来推断图片尺寸
只会相信开发者写在 HTML 里的 sizes


原则 2:响应式图片 = 声明 + 执行

  • 开发者:声明「图片在布局中会显示多宽」
  • 浏览器:根据 DPR + srcset 选择最合适的资源

原则 3:srcset(w) ≠ sizes

  • srcset:我有哪些尺寸的图片
  • sizes:图片最终会显示多宽(CSS px)

两者必须配对使用


二、强制规则(违反即不规范)

规则 1:只要使用 srcset(w 描述符),必须写 sizes

❌ 错误

html
1
<img srcset="img-600.jpg 600w, img-1200.jpg 1200w">

✅ 正确

html
1234
<img
  srcset="img-600.jpg 600w, img-1200.jpg 1200w"
  sizes="600px"
>

规则 2:桌面端优先使用 px,而不是 vw

❌ 不规范

html
1
sizes="(max-width: 1024px) 100vw, 40vw"

✅ 规范

html
1
sizes="(max-width: 1024px) 100vw, 600px"

说明:

  • 桌面布局通常是内容区设计常量
  • 使用 vw 会把 viewport ≠ content 的差异放大

规则 3:vw 只用于真正随 viewport 变化的场景

允许使用 vw

  • Hero / Banner
  • Masonry / auto grid
  • 全宽轮播

不允许使用 vw

  • 固定列数卡片
  • 固定宽 sidebar
  • 内容区内的列布局

规则 4:sizes 描述的是“设计意图”,不是 CSS 实现

❌ 不规范(试图复刻布局)

html
1
sizes="calc((100vw - 80px) / 2)"

✅ 规范(表达意图)

html
1
sizes="600px"

规则 5:sizes 必须有兜底值

❌ 错误

html
1
sizes="(max-width: 768px) 100vw"

✅ 正确

html
1
sizes="(max-width: 768px) 100vw, 600px"

三、标准使用模板(直接可复用)

模板 1:内容区 1200,一行两列(单图)

html
1234
sizes="
  (max-width: 1024px) 100vw,
  600px
"

模板 2:桌面三列卡片(1200 / 3)

html
12345
sizes="
  (max-width: 640px) 100vw,
  (max-width: 1024px) 50vw,
  400px
"

模板 3:Hero / Banner(最大内容宽 1440)

html
12345
sizes="
  (max-width: 768px) 100vw,
  (max-width: 1280px) 90vw,
  1440px
"

模板 4:缩略图 / 列表图

html
1234
sizes="
  (max-width: 640px) 120px,
  240px
"

模板 5:Avatar / Icon(不用 sizes)

html
123456
<img
  src="[email protected]"
  srcset="[email protected] 2x, [email protected] 3x"
  width="48"
  height="48"
>

四、picture 的规范用法

html
123456789101112131415161718192021222324
<picture>
  <source
    type="image/avif"
    srcset="img-320.avif 320w, img-640.avif 640w, img-1200.avif 1200w"
    sizes="(max-width: 1024px) 100vw, 600px"
  />

  <source
    type="image/webp"
    srcset="img-320.webp 320w, img-640.webp 640w, img-1200.webp 1200w"
    sizes="(max-width: 1024px) 100vw, 600px"
  />

  <img
    src="img-640.jpg"
    srcset="img-320.jpg 320w, img-640.jpg 640w, img-1200.jpg 1200w"
    sizes="(max-width: 1024px) 100vw, 600px"
    width="1200"
    height="800"
    alt=""
    loading="lazy"
    decoding="async"
  />
</picture>

五、自检清单(Code Review 用)

  • 是否使用了 srcset 却没有 sizes?
  • 桌面端是否错误使用了 vw?
  • sizes 是否能一句话解释清楚?
  • 同一页面是否所有图片 sizes 一样?
  • 是否明确区分 Hero / Card / Thumb?

任一项失败 → 需要修改


六、终极结论(牢记)

sizes 是你和浏览器之间的“布局合同”。
合同写错,浏览器一定严格执行错的结果。