Skip to content

srcset 与 sizes

srcsetsizes 是 HTML5 为响应式图片引入的两个属性,它们让浏览器能够根据设备屏幕宽度和像素密度,自动选择最合适的图片资源。本节将深入讲解这两个属性的语法、描述符类型以及实际配置方法。

前置知识

阅读本节前,建议先了解:图片尺寸与响应式图片

基础概念

在响应式设计中,不同设备可能需要不同尺寸或分辨率的图片。为手机用户提供一张 1920px 宽的大图是浪费带宽,而为桌面显示器提供 320px 的小图又会导致模糊。

srcset 属性允许你为 <img> 提供一组候选图片,浏览器根据屏幕条件自动选择最合适的版本。sizes 属性则告诉浏览器图片在不同屏幕宽度下的预期显示尺寸,帮助浏览器做出更精确的选择。

这两个属性可以独立使用,也可以配合使用以获得最佳效果。

语法

srcset 属性语法

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>srcset 属性</title>
</head>
<body>
  <h1>srcset 属性</h1>

  <!-- 像素密度描述符(x):适用于固定宽度布局 -->
  <img src="photo.jpg"
       srcset="photo-1x.jpg 1x,
               photo-2x.jpg 2x"
       alt="使用像素密度描述符的图片">

  <br>

  <!-- 宽度描述符(w):适用于响应式布局 -->
  <img src="photo-800.jpg"
       srcset="photo-400.jpg 400w,
               photo-800.jpg 800w,
               photo-1200.jpg 1200w"
       alt="使用宽度描述符的图片">
</body>
</html>

sizes 属性语法

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>sizes 属性</title>
</head>
<body>
  <h1>sizes 属性</h1>

  <!-- sizes 告诉浏览器在不同条件下的预期显示宽度 -->
  <img src="photo-default.jpg"
       srcset="photo-400.jpg 400w,
               photo-800.jpg 800w,
               photo-1200.jpg 1200w"
       sizes="(max-width: 480px) 100vw,
              (max-width: 900px) 50vw,
              400px"
       alt="配合 sizes 的响应式图片">
</body>
</html>

详细说明

像素密度描述符(x 描述符)

像素密度描述符以 x 为单位,表示设备的像素密度(DPR,Device Pixel Ratio):

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>像素密度描述符</title>
  <style>
    .avatar {
      width: 64px;
      height: 64px;
      border-radius: 50%;
    }
  </style>
</head>
<body>
  <h1>像素密度描述符</h1>

  <!-- 普通屏幕加载小图,高清屏幕加载大图 -->
  <img class="avatar"
       src="avatar-64.jpg"
       srcset="avatar-64.jpg 1x,
               avatar-128.jpg 2x,
               avatar-192.jpg 3x"
       alt="用户头像">

  <p>
    当设备像素比(DPR)为 1 时,加载 64x64 的图片;
    DPR 为 2 时(如 Retina 屏幕),加载 128x128 的图片;
    DPR 为 3 时,加载 192x192 的图片。
  </p>
</body>
</html>
描述符含义适用场景
1x1 倍像素密度(普通屏幕)基准图片
2x2 倍像素密度(Retina)高清屏幕
3x3 倍像素密度超高清屏幕

宽度描述符(w 描述符)

宽度描述符以 w 为单位,表示图片的实际文件宽度:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>宽度描述符</title>
</head>
<body>
  <h1>宽度描述符</h1>

  <!-- 宽度描述符需要配合 sizes 属性使用 -->
  <img src="photo-800.jpg"
       srcset="photo-400.jpg 400w,
               photo-800.jpg 800w,
               photo-1200.jpg 1200w,
               photo-1600.jpg 1600w"
       sizes="(max-width: 600px) 100vw,
              (max-width: 1200px) 75vw,
              600px"
       alt="使用宽度描述符的响应式图片"
       width="1600" height="1067">
</body>
</html>

浏览器选择逻辑

  1. 浏览器根据当前视口宽度和 sizes 条件,计算出图片需要的显示宽度
  2. 将显示宽度乘以设备像素比,得到图片的有效像素宽度
  3. srcset 中选择大于等于该宽度且最接近的图片版本

x 描述符 vs w 描述符

对比项x 描述符w 描述符
单位倍数(1x/2x/3x)像素宽度(400w/800w)
是否需要 sizes不需要需要
适用场景固定宽度区域响应式布局
灵活性较低较高
兼容性所有现代浏览器所有现代浏览器

sizes 属性的媒体条件

sizes 属性由一个或多个媒体条件 + 图片预期宽度组成:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>sizes 条件</title>
</head>
<body>
  <h1>sizes 属性的媒体条件</h1>

  <!-- 多条件匹配:从上到下评估,第一个匹配的条件生效 -->
  <img src="photo-800.jpg"
       srcset="photo-400.jpg 400w,
               photo-800.jpg 800w,
               photo-1200.jpg 1200w"
       sizes="(max-width: 360px) 100vw,
              (max-width: 768px) 80vw,
              (max-width: 1200px) 50vw,
              600px"
       alt="多条件 sizes 响应式图片"
       width="1200" height="800">

  <p>常见 sizes 值速记:</p>
  <ul>
    <li><code>100vw</code>:图片占满整个视口宽度</li>
    <li><code>50vw</code>:图片占视口宽度的一半</li>
    <li><code>calc(100vw - 40px)</code>:视口宽度减去边距</li>
    <li><code>600px</code>:固定 600px 宽度</li>
  </ul>
</body>
</html>

同时使用 x 和 w 描述符

不要混用描述符

一个 srcset 中只能使用一种描述符类型,要么全部用 x,要么全部用 w,不能混用。

html
<!-- 错误!混用 x 和 w 描述符 -->
<!-- <img srcset="photo-400.jpg 400w, photo-2x.jpg 2x" alt="错误"> -->

<!-- 正确:统一使用 w 描述符 -->
<img srcset="photo-400.jpg 400w, photo-800.jpg 800w" alt="正确">

<!-- 正确:统一使用 x 描述符 -->
<img srcset="photo.jpg 1x, photo-2x.jpg 2x" alt="正确">

实战示例

响应式文章配图

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>响应式文章配图</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      max-width: 800px;
      margin: 0 auto;
      padding: 20px;
      line-height: 1.8;
    }

    article img {
      width: 100%;
      height: auto;
      border-radius: 8px;
    }

    article figcaption {
      text-align: center;
      color: #888;
      font-size: 14px;
      margin-top: 8px;
    }
  </style>
</head>
<body>
  <article>
    <h1>为什么选择响应式图片</h1>
    <p>在当今多设备时代,响应式图片是提升用户体验和网站性能的关键技术。</p>

    <figure>
      <img src="responsive-800.jpg"
           srcset="responsive-400.jpg 400w,
                   responsive-800.jpg 800w,
                   responsive-1200.jpg 1200w"
           sizes="100vw"
           alt="不同设备上显示同一网站的对比图,从手机到桌面"
           width="1200" height="675"
           loading="lazy">
      <figcaption>图 1:同一个网站在不同设备上的显示效果</figcaption>
    </figure>

    <p>
      根据分析,移动端流量已占全球互联网流量的 60% 以上。
      使用 srcset 和 sizes 可以为不同设备提供恰当大小的图片,
      减少不必要的带宽消耗。
    </p>

    <figure>
      <img src="bandwidth-chart-800.jpg"
           srcset="bandwidth-chart-400.jpg 400w,
                   bandwidth-chart-800.jpg 800w"
           sizes="(max-width: 600px) 100vw, 800px"
           alt="移动端和桌面端带宽消耗对比柱状图"
           width="800" height="450"
           loading="lazy">
      <figcaption>图 2:响应式图片可减少 40~60% 的移动端图片带宽</figcaption>
    </figure>
  </article>
</body>
</html>

注意事项

  • srcset 中不能混用 xw 描述符
  • 使用 w 描述符时建议搭配 sizes 属性,否则浏览器默认图片占满视口
  • sizes 的最后一个值是默认值(无媒体条件),必须提供
  • sizes 只影响浏览器选择哪个候选图片,不影响图片的 CSS 显示尺寸
  • 图片的 CSS 显示尺寸仍由样式表控制
  • srcset 中的 src 属性是回退方案,不支持 srcset 的浏览器会使用 src

最佳实践

  • 根据布局类型选择描述符:固定宽度用 x,响应式布局用 w
  • 准备 3~4 个不同尺寸的候选图片,覆盖从手机到桌面
  • 始终提供 src 属性作为回退
  • 设置 HTML width/height 防止 CLS
  • 使用真实的图片文件,不要只准备一个版本然后在 HTML 中"假装"有多个
  • sizes 的值应与实际 CSS 布局一致,否则浏览器选择会不准确
  • 可以使用 <picture> 元素实现更复杂的响应式图片逻辑

下一节

继续学习:picture 与 source

参考链接