前置知识: CSS

响应式图片

00:00
3 min Intermediate 2026/6/14

HTML响应式图片详解:srcset、sizes、picture元素与艺术指导策略。

1. 响应式图片问题

1.1 核心挑战

  • 分辨率适配:1x/2x/3x 屏幕需要不同分辨率图片
  • 视口适配:不同视口宽度需要不同尺寸图片
  • 艺术指导:不同屏幕可能需要不同裁切/构图
  • 格式适配WebP/AVIF 等现代式需要降级方案

1.2 带宽浪费

移动端加载 2000px 宽的图片:
  - 下载 500KB 数据
  - 浏览器缩放到 375px 显示
  - 浪费 ~400KB 带宽

使用响应式图片:
  - 下载 375px 宽的图片
  - 仅需 ~50KB 数据
  - 节省 90% 带宽

2. srcset 属性

2.1 分辨率描述符

<img src="photo.jpg" srcset="photo-1x.jpg 1x, photo-2x.jpg 2x, photo-3x.jpg 3x" alt="描述" />

浏览器根据设备像素比(DPR)选择最合适的图片

设备DPR选择图片
普通显示器1xphoto-1x.jpg
Retina 显示器2xphoto-2x.jpg
端手机3xphoto-3x.jpg

2.2 宽度描述符

<img
  src="photo-800.jpg"
  srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w, photo-1600.jpg 1600w"
  alt="描述"
/>

400w 表示图片实际宽度为 400 像素。浏览器根据视口和 DPR 计算需要的图片尺寸。

3. sizes 属性

3.1 基本用法

sizes 告诉浏览器图片在页面中的显示尺寸,帮助浏览器在解析 HTML 阶段选择合适的图片

<img
  src="photo-800.jpg"
  srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
  sizes="(max-width: 600px) 100vw,
            (max-width: 1200px) 50vw,
            33vw"
  alt="描述"
/>

解析逻辑:

  • 视口 ≤ 600px:图片占 100% 视口
  • 视口 601-1200px:图片占 50% 视口
  • 视口 > 1200px:图片占 33% 视口

3.2 sizes 计算示例

视口宽度: 900px
sizes 匹配: 50vw → 图片显示宽度 = 450px
DPR: 2x
需要图片宽度: 450 × 2 = 900px
选择: photo-800.jpg(最接近且不小于 900px 的选项)

3.3 常见 sizes 模式

<!-- 全宽图片 -->
sizes="100vw"

<!-- 两列布局 -->
sizes="(max-width: 768px) 100vw, 50vw"

<!-- 三列网格 -->
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"

<!-- 侧边栏 + 主内容 -->
sizes="(max-width: 768px) 100vw, calc(100vw - 300px)"

4. picture 元素

4.1 艺术指导

<picture>
  <!-- 宽屏:横向构图 -->
  <source media="(min-width: 1024px)" srcset="photo-wide-1x.jpg 1x, photo-wide-2x.jpg 2x" />
  <!-- 平板:方形构图 -->
  <source media="(min-width: 640px)" srcset="photo-square-1x.jpg 1x, photo-square-2x.jpg 2x" />
  <!-- 手机:竖向构图 + 裁切 -->
  <img
    src="photo-portrait.jpg"
    srcset="photo-portrait-1x.jpg 1x, photo-portrait-2x.jpg 2x"
    alt="描述"
  />
</picture>

4.2 格式降级

<picture>
  <source type="image/avif" srcset="photo.avif" />
  <source type="image/webp" srcset="photo.webp" />
  <img src="photo.jpg" alt="描述" />
</picture>

浏览器<source> 顺序检查选择第一个支持式。

4.3 格式 + 尺寸组合

<picture>
  <source
    type="image/avif"
    srcset="photo-400.avif 400w, photo-800.avif 800w, photo-1200.avif 1200w"
    sizes="(max-width: 768px) 100vw, 50vw"
  />
  <source
    type="image/webp"
    srcset="photo-400.webp 400w, photo-800.webp 800w, photo-1200.webp 1200w"
    sizes="(max-width: 768px) 100vw, 50vw"
  />
  <img
    src="photo-800.jpg"
    srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
    sizes="(max-width: 768px) 100vw, 50vw"
    alt="描述"
  />
</picture>

5. 图片优化策略

5.1 尺寸断点设计

常见断点:
  320px  → 小手机
  640px  → 大手机
  768px  → 平板竖屏
  1024px → 平板横屏 / 小笔记本
  1280px → 桌面
  1920px → 大屏

图片宽度建议:
  320w, 640w, 960w, 1280w, 1920w

5.2 懒加载

<img
  src="photo.jpg"
  srcset="photo-400.jpg 400w, photo-800.jpg 800w"
  sizes="100vw"
  loading="lazy"
  decoding="async"
  alt="描述"
/>
属性说明
loading="lazy"视口图片延迟加载
decoding="async"异步解码,不阻塞渲染
fetchpriority="high"优先级加载(首屏 LCP 图片

5.3 首屏图片优化

<!-- LCP 图片:预加载 + 高优先级 -->
<link
  rel="preload"
  as="image"
  href="hero-800.webp"
  imagesrcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
  imagesizes="100vw"
  fetchpriority="high"
/>

<img
  src="hero-800.webp"
  srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
  sizes="100vw"
  fetchpriority="high"
  alt="Hero 图片"
/>

5.4 防止布局偏移(CLS)

<!-- 方式一:设置宽高属性 -->
<img src="photo.jpg" width="800" height="600" alt="描述" />

<!-- 方式二:CSS aspect-ratio -->
<img src="photo.jpg" style="aspect-ratio: 4/3; width: 100%;" alt="描述" />

6. 工具与自动化

5.1 图片生成

# 使用 sharp 生成多尺寸图片
npx sharp-cli -i photo.jpg -o photo-400.jpg resize 400
npx sharp-cli -i photo.jpg -o photo-800.jpg resize 800
npx sharp-cli -i photo.jpg -o photo-1200.jpg resize 1200

# 批量转换格式
npx sharp-cli -i "*.jpg" -o "./output/" format webp

5.2 构建工具集成

// Vite + vite-plugin-imagetools
import { defineConfig } from 'vite';
import imagetools from 'vite-imagetools';

export default defineConfig({
  plugins: [imagetools()],
});

使用:

<img
  src="/photo.jpg?format=webp&width=400;800;1200"
  srcset="/photo.jpg?width=400 400w, /photo.jpg?width=800 800w, /photo.jpg?width=1200 1200w"
  sizes="100vw"
  alt="描述"
/>

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式