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>可以同时使用media和type
source 元素的属性
| 属性 | 说明 | 示例 |
|---|---|---|
srcset | 图片候选集 | "small.webp 400w, large.webp 800w" |
sizes | 尺寸条件 | (max-width: 600px) 100vw |
type | MIME 类型 | 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