技术知识文章集合TECHNICAL ARCHIVE · 457 DOCUMENTS

显示模式

登录
ARCHIVE DOCUMENTCSS

img 标签中的 srcset 和 sizes 属性有什么用?picture、source 标签解决什么问题?

所属馆藏
CSS
文件格式
Markdown
原始路径
CSS/15-img标签中的srcset&size属性有什么用? picture 标签, source 标签解决什
本文目录9 个章节
  1. 1. 只使用 srcset 属性
  2. 2. srcset 属性与 sizes 属性配合使用
  3. 3. CSS image-set()
  4. 4. <picture> 标签与 <source> 标签
  5. 5. <source> 标签的 type 属性
  6. 6. srcset、sizes 与 <picture> 的选择
  7. 7. 常见注意事项
  8. 总结
  9. 参考资料

img 标签中的 srcsetsizes 属性有什么用?picturesource 标签解决什么问题?

Category(分类): CSS Status: 未知

本文保留原文关于 srcsetsizespicturesource 和 CSS image-set() 的主要内容,并修正 size/sizes 混用、w/x 描述符、媒体查询范围和资源选择逻辑等问题。

1. 只使用 srcset 属性

srcset 用于向浏览器提供多个候选图片资源。浏览器会根据候选资源的描述符、图片显示槽宽度、设备像素比、网络状况和用户偏好选择合适的资源。

它不需要 JavaScript,适合响应式图片加载。srcset 主要用于 <img><source>,而不是普通 CSS 背景图片。

使用 x 像素密度描述符

当图片在不同设备上的显示尺寸基本相同,只是设备像素比不同,可以使用 1x2x3x 等描述符:

<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.251.52.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 使用的是 1x2x,通常不需要 sizes

浏览器如何选择资源

浏览器大致按照以下过程选择图片:

  1. 根据 sizes 和当前媒体条件计算图片显示槽宽度;
  2. 结合设备像素比估算所需的资源分辨率;
  3. srcset 候选列表中选择合适资源;
  4. 根据网络状况、用户节省流量设置和浏览器策略进行最终取舍。

例如,视口宽度为 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="文章配图"
>

同时建议设置 widthheight,让浏览器提前计算宽高比,减少布局偏移(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">

因为 500px501px 之间可能存在小数 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> 出现的顺序检查条件,通常使用第一个同时满足 mediatype 和资源条件的 <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 负责选择图片场景,srcsetsizes 负责在该场景内选择合适的资源,它们可以配合使用。

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 扩展名。

浏览器会依次检查:

  1. type 指定的 MIME 类型是否支持;
  2. media(如果存在)是否匹配;
  3. srcset 是否提供可用候选。

一旦某个 <source> 匹配,浏览器就不会继续选择后面的 <source>。如果都不匹配,使用 <img>srcsrcset

使用现代图片格式的注意事项

<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. srcsetsizes<picture> 的选择

只需要不同 DPR 的同一构图

使用 srcsetx 描述符:

<img
  srcset="logo.png 1x, logo@2x.png 2x"
  src="logo.png"
  alt="Logo"
>

图片显示宽度随容器变化

使用 srcsetw 描述符和 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. 常见注意事项

  1. srcsetxw 描述符不能在同一个候选列表中混用;
  2. 使用 w 描述符时,sizes 应尽量与真实 CSS 布局一致;
  3. sizes 不能单独让浏览器选择图片,它需要与 srcsetw 候选配合;
  4. src 是重要的兼容回退,不要随意删除;
  5. <picture> 内必须保留 <img>
  6. <source> 的顺序很重要,更具体或更优先的条件应放在前面;
  7. 图片内容应提供准确的 alt,装饰性图片可以使用空的 alt=""
  8. 为图片设置 widthheight,避免加载后发生布局偏移;
  9. 首屏最大内容图片不要盲目设置 loading="lazy"
  10. srcset 负责资源选择,不负责裁剪图片构图;需要艺术指导(art direction)时使用 <picture>
  11. 图片的候选 URL 应尽量使用稳定的本地路径、CDN 路径或构建工具生成的资源路径;
  12. 浏览器可能因为网络状况和节省流量策略选择不同候选资源,因此不要把候选选择结果当作绝对保证。

总结

  • srcset 可以让浏览器在多个图片资源中进行选择,不需要 JavaScript;
  • x 描述符用于像素密度候选,w 描述符用于图片资源宽度候选;
  • w 描述符通常需要配合 sizes,由 sizes 告诉浏览器图片预计显示多宽;
  • sizes 不是图片的实际尺寸,也不是 size 属性;
  • <picture> 用于根据媒体条件或图片格式选择不同资源;
  • <source> 可以使用 mediatypesrcsetsizes
  • <img><picture> 中不可缺少的回退元素;
  • CSS image-set() 主要用于背景图片,与 <img srcset> 的语义和用途不同;
  • 响应式图片还应结合图片压缩、尺寸属性、缓存、CDN 和可访问性一起设计。

参考资料

457 DOCUMENTS · 10 COLLECTIONS
ARCHIVE SEARCH457 篇文章

SEARCH GUIDE

输入关键词开始搜索

支持搜索文章标题、所属分类和原始文档路径。

按分类浏览

10 COLLECTIONS