Skip to content

picture 与 source

<picture> 元素是 HTML5 为响应式图片提供的高级容器,通过 <source> 子元素实现艺术指导(Art Direction)格式协商(Format Negotiation)。本节将介绍 <picture> 的工作原理、使用场景及与 <img> srcset 的区别。

前置知识

阅读本节前,建议先了解:srcset 与 sizes

基础概念

<picture> 是 HTML5 引入的响应式图片容器元素。它本身不直接显示图片,而是通过内部的 <source> 子元素定义不同条件下的图片源,最终的 <img> 元素负责显示。

<picture> 适合两种场景:艺术指导(Art Direction)——在不同屏幕上裁剪或调整图片构图;以及格式协商(Format Negotiation)——为支持新格式的浏览器提供 WebP/AVIF,为不支持的浏览器回退到 JPEG/PNG。

语法

基本语法

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>picture 元素</title>
</head>
<body>
  <h1>picture 基本语法</h1>

  <!-- picture 包含多个 source 和一个回退 img -->
  <picture>
    <!-- source 按顺序匹配,第一个符合条件的生效 -->
    <source media="(max-width: 600px)" srcset="photo-square.jpg">
    <source media="(min-width: 601px)" srcset="photo-landscape.jpg">
    <!-- img 是回退,所有 source 都不匹配时显示 -->
    <img src="photo-default.jpg" alt="照片">
  </picture>
</body>
</html>

格式协商

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>格式协商</title>
</head>
<body>
  <h1>格式协商</h1>

  <!-- 优先提供 AVIF,不支持则回退到 WebP,再回退到 JPEG -->
  <picture>
    <source type="image/avif" srcset="photo.avif">
    <source type="image/webp" srcset="photo.webp">
    <img src="photo.jpg" alt="照片">
  </picture>
</body>
</html>

详细说明

艺术指导(Art Direction)

艺术指导是指根据不同屏幕尺寸,提供不同构图或裁剪的图片版本:

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>
    .hero img {
      width: 100%;
      height: auto;
      display: block;
    }
  </style>
</head>
<body>
  <h1>艺术指导示例</h1>

  <!--
    手机:使用人物特写裁剪(方形/竖构图)
    平板:使用中等裁剪
    桌面:使用完整横构图
  -->
  <picture>
    <!-- 手机:竖屏特写 -->
    <source media="(max-width: 480px)"
            srcset="team-portrait-close.webp"
            type="image/webp">
    <source media="(max-width: 480px)"
            srcset="team-portrait-close.jpg">

    <!-- 平板:中等裁剪 -->
    <source media="(max-width: 1024px)"
            srcset="team-portrait-medium.webp"
            type="image/webp">
    <source media="(max-width: 1024px)"
            srcset="team-portrait-medium.jpg">

    <!-- 桌面:完整全景 -->
    <source type="image/webp" srcset="team-panorama.webp">

    <!-- 回退 -->
    <img src="team-panorama.jpg"
         alt="公司 20 人产品团队的全景合影"
         width="1920" height="800">
  </picture>
</body>
</html>

格式协商(Format Negotiation)

浏览器按 <source> 顺序检查 type 属性,使用第一个它支持的格式:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>格式协商</title>
</head>
<body>
  <h1>格式协商</h1>

  <!-- AVIF + WebP + JPEG 三级回退 -->
  <picture>
    <!-- 优先 AVIF(压缩率最高) -->
    <source type="image/avif"
            srcset="photo-small.avif 400w,
                    photo-medium.avif 800w,
                    photo-large.avif 1200w"
            sizes="(max-width: 600px) 100vw, 800px">

    <!-- 其次 WebP(兼容性好) -->
    <source type="image/webp"
            srcset="photo-small.webp 400w,
                    photo-medium.webp 800w,
                    photo-large.webp 1200w"
            sizes="(max-width: 600px) 100vw, 800px">

    <!-- 回退 JPEG -->
    <img src="photo-medium.jpg"
         srcset="photo-small.jpg 400w,
                 photo-medium.jpg 800w,
                 photo-large.jpg 1200w"
         sizes="(max-width: 600px) 100vw, 800px"
         alt="风景照片"
         width="1200" height="800">
  </picture>
</body>
</html>

picture vs img srcset

对比项<picture><img> srcset
选择权开发者预定义条件浏览器自动选择
适用场景艺术指导、格式协商同构图不同尺寸
灵活性高(media + type)中(尺寸 + 密度)
代码复杂度较高较低
回退机制<img> 子元素src 属性

选择建议

  • 如果只是不同屏幕需要不同尺寸的同一图片 → 使用 <img srcset sizes>
  • 如果不同屏幕需要不同构图/裁剪 → 使用 <picture>
  • 如果需要提供不同格式(AVIF/WebP) → 使用 <picture>
  • 如果两者都需要 → <picture><source> 可以同时使用 mediatype

source 元素的属性

属性说明示例
srcset图片候选集"small.webp 400w, large.webp 800w"
sizes尺寸条件(max-width: 600px) 100vw
typeMIME 类型image/webp
media媒体查询条件(max-width: 600px)

实战示例

电商产品主图

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>产品主图 - picture</title>
  <style>
    .product-image {
      width: 100%;
      max-width: 600px;
    }
    .product-image img {
      width: 100%;
      height: auto;
      border-radius: 8px;
    }
  </style>
</head>
<body>
  <h1>无线蓝牙耳机</h1>

  <div class="product-image">
    <picture>
      <!-- 手机端:正面特写 -->
      <source media="(max-width: 480px)"
              srcset="earbuds-front-close.avif" type="image/avif">
      <source media="(max-width: 480px)"
              srcset="earbuds-front-close.webp" type="image/webp">
      <source media="(max-width: 480px)"
              srcset="earbuds-front-close.jpg">

      <!-- 桌面端:产品全景 -->
      <source srcset="earbuds-panorama.avif" type="image/avif">
      <source srcset="earbuds-panorama.webp" type="image/webp">

      <!-- 回退 -->
      <img src="earbuds-panorama.jpg"
           alt="SoundMax Pro 无线蓝牙耳机产品全景图"
           width="600" height="600"
           loading="eager">
    </picture>
  </div>

  <p>主动降噪,续航 30 小时。</p>
</body>
</html>

注意事项

  • <picture>必须包含一个 <img> 元素作为回退
  • <source> 按顺序匹配,第一个匹配的条件生效
  • <img>src 属性是不支持 <picture> 的浏览器的回退
  • <picture> 本身不设置样式,样式应设置在内部的 <img>
  • media 属性不适用于 <video> 中的 <source>
  • 不要在 <picture> 中只用 type 做格式协商,而不做尺寸优化

最佳实践

  • 优先使用 <img srcset> 进行尺寸优化,只在需要艺术指导时使用 <picture>
  • 格式协商推荐 AVIF → WebP → JPEG 的三级回退
  • 始终为 <img> 设置 width/height 防止 CLS
  • <source>type 属性使用完整的 MIME 类型(如 image/webp
  • 将最新的格式(AVIF)放在最前面,最兼容的格式(JPEG)放在 <img> 回退中

下一节

继续学习:figure 与 figcaption

参考链接