img 标签中的 srcset 和 sizes 属性有什么用?picture、source 标签解决什么问题?
Category(分类): CSS Status: 未知
本文保留原文关于
srcset、sizes、picture、source和 CSSimage-set()的主要内容,并修正size/sizes混用、w/x描述符、媒体查询范围和资源选择逻辑等问题。
1. 只使用 srcset 属性
srcset 用于向浏览器提供多个候选图片资源。浏览器会根据候选资源的描述符、图片显示槽宽度、设备像素比、网络状况和用户偏好选择合适的资源。
它不需要 JavaScript,适合响应式图片加载。srcset 主要用于 <img> 和 <source>,而不是普通 CSS 背景图片。
使用 x 像素密度描述符
当图片在不同设备上的显示尺寸基本相同,只是设备像素比不同,可以使用 1x、2x、3x 等描述符:
<img
srcset="
foo-320.jpg 1x,
foo-480.jpg 1.5x,
foo-640.jpg 2x
"
src="foo-320.jpg"
alt="示例图片"
>
像素密度描述符的格式是“倍率 + x”:
1x表示一倍设备像素比;2x表示二倍设备像素比;3x表示三倍设备像素比;1x可以省略,未写描述符时通常按1x处理。
如果图片显示宽度固定为 320 CSS px,那么:
foo-320.jpg 1x适合 DPR 约为 1 的设备;foo-640.jpg 2x适合 DPR 约为 2 的设备。
设备像素比并不只有整数值,1.25、1.5、2.625 等都可能出现。浏览器也不一定严格按照 DPR 选择资源,还可能结合网络速度和节省流量设置进行取舍。
x 描述符适合显示槽尺寸已知或变化不大的场景,并不是“只有固定宽度的图片才能使用”。如果图片显示宽度会随着视口变化,应使用 w 描述符和 sizes。
如果浏览器不支持 srcset,会使用 src 作为回退资源。因此建议始终保留 src:
<img
srcset="image-1x.jpg 1x, image-2x.jpg 2x"
src="image-1x.jpg"
width="320"
height="200"
alt="示例图片"
>
2. srcset 属性与 sizes 属性配合使用
原文中的“size 属性”应为 sizes 属性。sizes 不是图片实际尺寸,而是告诉浏览器:
在当前媒体条件下,图片预计占据多宽的 CSS 像素空间。
当图片会根据屏幕宽度显示不同大小时,应使用 w 宽度描述符,并配合 sizes:
<img
srcset="
foo-160.jpg 160w,
foo-320.jpg 320w,
foo-640.jpg 640w,
foo-1280.jpg 1280w
"
sizes="
(max-width: 440px) 100vw,
(max-width: 900px) 33vw,
254px
"
src="foo-1280.jpg"
alt="示例图片"
>
w 宽度描述符
w 描述符表示对应图片资源的固有宽度,例如:
foo-160.jpg 160w
表示该图片资源适合按照 160 CSS px 左右的显示宽度参与选择。它不是 CSS 样式,也不是要求浏览器必须以 160px 显示图片。
sizes 的写法
sizes 是由逗号分隔的列表:
媒体条件 显示槽宽度, 媒体条件 显示槽宽度, 默认显示槽宽度
除了最后一个默认值外,前面的每一项都由媒体条件和长度组成:
sizes="
(max-width: 440px) 100vw,
(max-width: 900px) 33vw,
254px
"
上例表示:
- 视口宽度不超过
440px时,图片显示宽度约为视口宽度的100%; - 视口宽度大于
440px且不超过900px时,图片显示宽度约为视口宽度的33%; - 其他情况使用
254px作为预估显示宽度。
sizes 中的最后一项是默认值,不应该再写媒体查询。sizes 必须与使用 w 描述符的 srcset 配合才有完整意义;如果 srcset 使用的是 1x、2x,通常不需要 sizes。
浏览器如何选择资源
浏览器大致按照以下过程选择图片:
- 根据
sizes和当前媒体条件计算图片显示槽宽度; - 结合设备像素比估算所需的资源分辨率;
- 在
srcset候选列表中选择合适资源; - 根据网络状况、用户节省流量设置和浏览器策略进行最终取舍。
例如,视口宽度为 480px 时,33vw 等于:
480 × 0.33 = 158.4 CSS px
浏览器可能选择 160w 的图片,但这不是因为计算结果恰好等于 160px,而是因为 160w 是候选列表中较合适的资源。DPR 为 2 时,浏览器可能倾向于选择更大的候选资源。
sizes 与图片布局必须一致
sizes 是开发者对图片显示宽度的声明。如果它与实际 CSS 布局不一致,浏览器可能选择过大或过小的图片:
.article-image {
display: block;
width: 100%;
height: auto;
}
对应可以写成:
<img
srcset="article-480.jpg 480w, article-960.jpg 960w"
sizes="(max-width: 700px) 100vw, 700px"
src="article-960.jpg"
width="960"
height="540"
alt="文章配图"
>
同时建议设置 width 和 height,让浏览器提前计算宽高比,减少布局偏移(CLS)。

3. CSS image-set()
CSS 的 image-set() 也可以根据分辨率选择背景图片,但它与 <img srcset> 解决的问题不同:
srcset主要用于内容图片;image-set()主要用于 CSS 背景或其他 CSS 图像值;image-set()不提供alt,不适合承载重要内容;- CSS 背景图片不参与
<img>的替代文本和图片语义。
.hero {
background-image: image-set(
url('../images/pic-1.jpg') 1x,
url('../images/pic-2.jpg') 2x,
url('../images/pic-3.jpg') 3x
);
}
旧项目中可能会看到:
.hero {
background-image: -webkit-image-set(
url('../images/pic-1.jpg') 1x,
url('../images/pic-2.jpg') 2x
);
background-image: image-set(
url('../images/pic-1.jpg') 1x,
url('../images/pic-2.jpg') 2x
);
}
-webkit-image-set() 是历史前缀写法。实际项目应结合目标浏览器测试,并准备合适的普通 background-image 回退。
4. <picture> 标签与 <source> 标签
如果只需要在同一张图片的不同分辨率之间选择,<img srcset> 通常已经足够。但如果还需要根据屏幕尺寸选择不同构图、根据图片格式选择资源,就可以使用 <picture> 和 <source>。
<picture> 是图片资源选择容器,内部通常包含一个或多个 <source> 和最后的 <img> 回退元素:
<picture>
<source
media="(max-width: 500px)"
srcset="cat-vertical.jpg"
>
<img
src="cat-horizontal.jpg"
alt="Cat"
>
</picture>
上例中:
- 视口宽度不超过
500px时,尝试使用竖版图片; - 其他情况使用
<img>的横版图片; <img>是必需的回退元素,也负责提供alt和兼容处理。
不建议使用下面这种写法:
<source media="(max-width: 500px)" srcset="cat-vertical.jpg">
<source media="(min-width: 501px)" srcset="cat-horizontal.jpg">
因为 500px 到 501px 之间可能存在小数 CSS 像素范围。使用一个带 media 的 <source>,让 <img> 作为默认分支更加简单。
<picture> 同时适配尺寸和像素密度
<picture>
<source
media="(min-width: 990px)"
srcset="
homepage-person-desktop.png,
homepage-person-desktop-2x.png 2x
"
>
<source
media="(min-width: 750px)"
srcset="
homepage-person-tablet.png,
homepage-person-tablet-2x.png 2x
"
>
<img
srcset="
homepage-person-mobile.png,
homepage-person-mobile-2x.png 2x
"
src="homepage-person-mobile.png"
alt="Shopify Merchant, Corrine Anestopoulos"
>
</picture>
浏览器会按照 <source> 出现的顺序检查条件,通常使用第一个同时满足 media、type 和资源条件的 <source>。如果没有匹配的 <source>,就使用 <img>。
如果 <source> 使用 w 描述符,则仍然可以配置 sizes:
<picture>
<source
media="(min-width: 750px)"
srcset="tablet-480.jpg 480w, tablet-960.jpg 960w"
sizes="50vw"
>
<img
src="mobile.jpg"
alt="示例图片"
>
</picture>
media 负责选择图片场景,srcset 和 sizes 负责在该场景内选择合适的资源,它们可以配合使用。
5. <source> 标签的 type 属性
<picture> 还可以根据浏览器支持的图片格式选择资源。例如优先使用 SVG,其次使用 WebP,最后回退到 PNG:
<picture>
<source
type="image/svg+xml"
srcset="logo.svg"
>
<source
type="image/webp"
srcset="logo.webp"
>
<img
src="logo.png"
alt="ACME Corp"
>
</picture>
原文中的 type="image/svg+xml" srcset="logo.xml" 扩展名容易造成误解,SVG 文件通常应使用 .svg 扩展名。
浏览器会依次检查:
type指定的 MIME 类型是否支持;media(如果存在)是否匹配;srcset是否提供可用候选。
一旦某个 <source> 匹配,浏览器就不会继续选择后面的 <source>。如果都不匹配,使用 <img> 的 src 或 srcset。
使用现代图片格式的注意事项
<picture>
<source
type="image/avif"
srcset="photo.avif"
>
<source
type="image/webp"
srcset="photo.webp"
>
<img
src="photo.jpg"
width="800"
height="500"
alt="风景图片"
>
</picture>
不要只因为格式新就假设文件一定更小,应结合图片内容、压缩参数和实际网络环境测试。<picture> 也不能替代图片压缩、响应式尺寸、缓存和 CDN 优化。
6. srcset、sizes 与 <picture> 的选择
只需要不同 DPR 的同一构图
使用 srcset 的 x 描述符:
<img
srcset="logo.png 1x, logo@2x.png 2x"
src="logo.png"
alt="Logo"
>
图片显示宽度随容器变化
使用 srcset 的 w 描述符和 sizes:
<img
srcset="card-320.jpg 320w, card-640.jpg 640w, card-1280.jpg 1280w"
sizes="(max-width: 768px) 100vw, 33vw"
src="card-640.jpg"
alt="卡片图片"
>
需要不同构图或不同媒体条件
使用 <picture> 和 media:
<picture>
<source media="(max-width: 600px)" srcset="hero-mobile.jpg">
<img src="hero-desktop.jpg" alt="页面主视觉">
</picture>
需要根据格式支持选择图片
使用 <picture> 和 type:
<picture>
<source type="image/avif" srcset="hero.avif">
<source type="image/webp" srcset="hero.webp">
<img src="hero.jpg" alt="页面主视觉">
</picture>
7. 常见注意事项
srcset的x和w描述符不能在同一个候选列表中混用;- 使用
w描述符时,sizes应尽量与真实 CSS 布局一致; sizes不能单独让浏览器选择图片,它需要与srcset的w候选配合;src是重要的兼容回退,不要随意删除;<picture>内必须保留<img>;<source>的顺序很重要,更具体或更优先的条件应放在前面;- 图片内容应提供准确的
alt,装饰性图片可以使用空的alt=""; - 为图片设置
width和height,避免加载后发生布局偏移; - 首屏最大内容图片不要盲目设置
loading="lazy"; srcset负责资源选择,不负责裁剪图片构图;需要艺术指导(art direction)时使用<picture>;- 图片的候选 URL 应尽量使用稳定的本地路径、CDN 路径或构建工具生成的资源路径;
- 浏览器可能因为网络状况和节省流量策略选择不同候选资源,因此不要把候选选择结果当作绝对保证。
总结
srcset可以让浏览器在多个图片资源中进行选择,不需要 JavaScript;x描述符用于像素密度候选,w描述符用于图片资源宽度候选;w描述符通常需要配合sizes,由sizes告诉浏览器图片预计显示多宽;sizes不是图片的实际尺寸,也不是size属性;<picture>用于根据媒体条件或图片格式选择不同资源;<source>可以使用media、type、srcset和sizes;<img>是<picture>中不可缺少的回退元素;- CSS
image-set()主要用于背景图片,与<img srcset>的语义和用途不同; - 响应式图片还应结合图片压缩、尺寸属性、缓存、CDN 和可访问性一起设计。