Skip to content

<picture> 标签

<picture> 标签用于包含零个或多个 <source> 元素和一个 <img> 元素,以实现响应式图片功能。它允许根据设备特性(如屏幕尺寸、分辨率等)提供不同的图片资源。

概述

<picture> 标签是 HTML5 中引入的语义化标签,用于实现响应式图片功能。它为不同的设备条件提供不同的图片源,确保在各种设备上都能显示最适合的图片。

语法

html
<picture>
  <source srcset="image-large.jpg" media="(min-width: 1200px)">
  <source srcset="image-medium.jpg" media="(min-width: 768px)">
  <img src="image-small.jpg" alt="描述">
</picture>

基本用法

基于屏幕尺寸的响应式图片

html
<picture>
  <source media="(min-width: 1200px)" srcset="large.jpg">
  <source media="(min-width: 768px)" srcset="medium.jpg">
  <img src="small.jpg" alt="响应式图片示例">
</picture>

基于设备像素比的图片

html
<picture>
  <source srcset="image-2x.jpg 2x, image-3x.jpg 3x">
  <img src="image-1x.jpg" alt="高分辨率图片">
</picture>

实际示例

响应式图片画廊

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>
    .gallery {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
      gap: 2rem;
      padding: 2rem;
    }
    
    figure {
      margin: 0;
      background-color: white;
      border-radius: 8px;
      box-shadow: 0 2px 10px rgba(0,0,0,0.1);
      overflow: hidden;
    }
    
    picture {
      display: block;
    }
    
    picture img {
      width: 100%;
      height: auto;
      display: block;
    }
    
    figcaption {
      padding: 1rem;
      text-align: center;
      font-style: italic;
      color: #666;
      background-color: #f8f9fa;
    }
  </style>
</head>
<body>
  <h1>响应式图片画廊</h1>
  
  <div class="gallery">
    <figure>
      <picture>
        <source media="(min-width: 1200px)" srcset="https://via.placeholder.com/600x400/FF6B6B/FFFFFF?text=大图">
        <source media="(min-width: 768px)" srcset="https://via.placeholder.com/400x300/FF6B6B/FFFFFF?text=中图">
        <img src="https://via.placeholder.com/300x200/FF6B6B/FFFFFF?text=小图" alt="日出景象">
      </picture>
      <figcaption>美丽的日出景象 - 响应式图片示例</figcaption>
    </figure>
    
    <figure>
      <picture>
        <source media="(min-width: 1200px)" srcset="https://via.placeholder.com/600x400/4ECDC4/FFFFFF?text=大图">
        <source media="(min-width: 768px)" srcset="https://via.placeholder.com/400x300/4ECDC4/FFFFFF?text=中图">
        <img src="https://via.placeholder.com/300x200/4ECDC4/FFFFFF?text=小图" alt="山脉风景">
      </picture>
      <figcaption>雄伟的山脉风景 - 响应式图片示例</figcaption>
    </figure>
    
    <figure>
      <picture>
        <source media="(min-width: 1200px)" srcset="https://via.placeholder.com/600x400/45B7D1/FFFFFF?text=大图">
        <source media="(min-width: 768px)" srcset="https://via.placeholder.com/400x300/45B7D1/FFFFFF?text=中图">
        <img src="https://via.placeholder.com/300x200/45B7D1/FFFFFF?text=小图" alt="海洋景色">
      </picture>
      <figcaption>宁静的海洋景色 - 响应式图片示例</figcaption>
    </figure>
  </div>
</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>
    .art-directed-image {
      max-width: 100%;
      margin: 2rem auto;
      padding: 0 1rem;
    }
    
    picture {
      display: block;
    }
    
    img {
      width: 100%;
      height: auto;
      border-radius: 8px;
      box-shadow: 0 4px 15px rgba(0,0,0,0.1);
    }
  </style>
</head>
<body>
  <h1>艺术指导示例</h1>
  
  <div class="art-directed-image">
    <picture>
      <!-- 横屏设备显示横图 -->
      <source media="(min-width: 1024px) and (orientation: landscape)" 
              srcset="https://via.placeholder.com/1200x600/667eea/ffffff?text=横屏大图">
      <!-- 竖屏设备显示竖图 -->
      <source media="(max-width: 767px) and (orientation: portrait)" 
              srcset="https://via.placeholder.com/400x600/667eea/ffffff?text=竖屏小图">
      <!-- 默认图片 -->
      <img src="https://via.placeholder.com/800x400/667eea/ffffff?text=默认图片" 
           alt="根据设备方向显示不同构图的图片">
    </picture>
  </div>
  
  <p>这个示例展示了如何根据不同设备的方向显示不同构图的图片,这被称为"艺术指导"。</p>
</body>
</html>

多种图片格式支持

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>图片格式支持</title>
  <style>
    .format-example {
      max-width: 600px;
      margin: 2rem auto;
      padding: 0 1rem;
    }
    
    picture {
      display: block;
      margin-bottom: 1rem;
    }
    
    img {
      width: 100%;
      height: auto;
      border-radius: 8px;
    }
    
    .description {
      background-color: #f8f9fa;
      padding: 1rem;
      border-radius: 8px;
      border-left: 4px solid #007bff;
    }
  </style>
</head>
<body>
  <h1>现代图片格式支持</h1>
  
  <div class="format-example">
    <picture>
      <!-- WebP 格式(现代浏览器) -->
      <source type="image/webp" srcset="https://via.placeholder.com/600x400/20bf6b/ffffff?text=WebP+图片">
      <!-- AVIF 格式(最新浏览器) -->
      <source type="image/avif" srcset="https://via.placeholder.com/600x400/20bf6b/ffffff?text=AVIF+图片">
      <!-- 默认 JPEG 格式 -->
      <img src="https://via.placeholder.com/600x400/20bf6b/ffffff?text=JPEG+图片" 
           alt="支持多种现代图片格式的示例">
    </picture>
    
    <div class="description">
      <h3>图片格式说明</h3>
      <p>这个示例展示了如何为不同浏览器提供不同格式的图片:</p>
      <ul>
        <li>支持 AVIF 的浏览器会加载 AVIF 格式图片</li>
        <li>支持 WebP 但不支持 AVIF 的浏览器会加载 WebP 格式图片</li>
        <li>不支持现代格式的浏览器会加载默认的 JPEG 格式图片</li>
      </ul>
    </div>
  </div>
</body>
</html>

与相关标签的区别

与单独使用 img 的区别

html
<!-- 传统方式:单一图片 -->
<img src="image.jpg" alt="图片描述">

<!-- 响应式方式:根据条件提供不同图片 -->
<picture>
  <source media="(min-width: 1200px)" srcset="large.jpg">
  <source media="(min-width: 768px)" srcset="medium.jpg">
  <img src="small.jpg" alt="图片描述">
</picture>

与 CSS 媒体查询的区别

html
<!-- picture 标签:在 HTML 层面提供不同图片 -->
<picture>
  <source media="(min-width: 768px)" srcset="desktop.jpg">
  <img src="mobile.jpg" alt="响应式图片">
</picture>

<!-- CSS 媒体查询:使用同一图片但应用不同样式 -->
<img src="image.jpg" alt="图片" class="responsive-image">

<style>
.responsive-image {
  width: 100%;
}

@media (min-width: 768px) {
  .responsive-image {
    max-width: 500px;
  }
}
</style>

高级用法

结合 srcset 和 sizes 属性

html
<picture>
  <source media="(min-width: 1200px)" 
          srcset="large-1x.jpg 1x, large-2x.jpg 2x"
          sizes="50vw">
  <source media="(min-width: 768px)" 
          srcset="medium-1x.jpg 1x, medium-2x.jpg 2x"
          sizes="75vw">
  <img src="small-1x.jpg" 
       srcset="small-1x.jpg 1x, small-2x.jpg 2x"
       sizes="100vw"
       alt="高级响应式图片示例">
</picture>

多重条件组合

html
<picture>
  <!-- 高分辨率大屏幕 -->
  <source media="(min-width: 1200px) and (min-resolution: 2dppx)" 
          srcset="large-2x.jpg">
  <!-- 普通大屏幕 -->
  <source media="(min-width: 1200px)" 
          srcset="large-1x.jpg">
  <!-- 高分辨率中等屏幕 -->
  <source media="(min-width: 768px) and (min-resolution: 2dppx)" 
          srcset="medium-2x.jpg">
  <!-- 普通中等屏幕 -->
  <source media="(min-width: 768px)" 
          srcset="medium-1x.jpg">
  <!-- 默认小屏幕 -->
  <img src="small-1x.jpg" 
       srcset="small-1x.jpg, small-2x.jpg 2x"
       alt="多重条件响应式图片">
</picture>

最佳实践

  1. 始终包含 img 标签<picture> 元素必须包含一个 <img> 元素作为备选方案
  2. 顺序很重要:浏览器会按顺序检查 <source> 元素,匹配第一个符合条件的
  3. 提供合适的备选方案:确保 <img> 标签的 src 属性指向一个合适的默认图片
  4. 使用适当的媒体查询:根据实际需求设置媒体查询条件
  5. 考虑性能:为不同设备提供适当尺寸的图片以优化加载速度

浏览器兼容性

<picture> 标签在现代浏览器中得到良好支持:

  • Chrome 38+
  • Firefox 38+
  • Safari 9.1+
  • Edge 13+
  • Internet Explorer 不支持

对于不支持的旧浏览器,会自动降级到 <img> 标签:

html
<!-- 不支持 <picture> 的浏览器会忽略它,直接显示 <img> -->
<picture>
  <source media="(min-width: 768px)" srcset="large.jpg">
  <img src="small.jpg" alt="向后兼容的响应式图片">
</picture>

注意事项

  1. <picture> 标签是容器元素,本身不显示任何内容
  2. 必须包含一个 <img> 元素作为最后一个子元素
  3. 可以包含多个 <source> 元素
  4. 浏览器按顺序检查 <source> 元素,使用第一个匹配的
  5. 不支持 <picture> 的浏览器会忽略它,直接显示 <img>

相关标签