picture 元素与响应式图片
本教程共 110 篇 · 第 35 篇 · 更新于 2026-07-28 · 约 7 分钟阅读
35. picture 元素与响应式图片
本节目标:学会用 srcset 和 picture 让浏览器自动选择最佳图片,解决不同屏幕尺寸和分辨率的图片适配问题。
一张 2000px 的大图,在手机上显示浪费流量,在高屏上又可能模糊。响应式图片就是解决这个问题的。
两种核心场景
响应式图片解决两个不同的问题:
- 分辨率切换:同一张图,大屏显示大文件、小屏显示小文件
- 美术设计(Art Direction):不同屏幕显示不同裁剪的图
分辨率切换:srcset + sizes
srcset 告诉浏览器”我有这些版本可选”,sizes 告诉浏览器”在不同屏幕下图片显示多大”。
<img
srcset="hero-480w.jpg 480w,
hero-800w.jpg 800w,
hero-1200w.jpg 1200w"
sizes="(max-width: 600px) 480px,
(max-width: 1000px) 800px,
1200px"
src="hero-800w.jpg"
alt="首页大图" />
逐行解析:
srcset:三个版本,分别标注了宽度(480w、800w、1200w)。w是图片的固有宽度sizes:三条规则。屏幕 ≤ 600px 时图片显示 480px 宽,屏幕 ≤ 1000px 时显示 800px 宽,其余显示 1200px 宽src:老浏览器的后备方案
浏览器的工作流程:
- 看屏幕宽度和像素密度
- 根据 sizes 确定图片显示宽度
- 从 srcset 里选最接近的图片加载
Note如果屏幕宽度 600px 但像素密度是 2x(Retina 屏),浏览器会加载 800w 甚至 1200w 的版本,保证清晰度。
分辨率切换:x 描述符
如果你不需要根据屏幕宽度切换,只需要为高分辨屏提供高清版,用 x 描述符更简单:
<img
srcset="logo.png,
logo@2x.png 2x"
src="logo.png"
alt="Logo" />
普通屏幕加载 logo.png,高分辨屏加载 logo@2x.png。不需要写 sizes。
美术设计:picture 元素
有时候你需要的不只是缩放,而是完全不同的图片。
比如桌面端显示一张宽风景图,手机端显示一张竖向特写图。
<picture>
<source media="(max-width: 799px)" srcset="portrait.jpg" />
<source media="(min-width: 800px)" srcset="landscape.jpg" />
<img src="landscape.jpg" alt="产品展示" />
</picture>
工作流程:
- 浏览器检查
<source>的media条件 - 第一个匹配的
<source>被选中 - 如果没有匹配的,或者浏览器不支持
<picture>,就用<img>作为后备
Important
<picture>里必须有一个<img>作为最后一个子元素。没有它,任何情况下都不会显示图片。
source 的 type 属性
还可以根据浏览器支持的格式来选择:
<picture>
<source type="image/avif" srcset="photo.avif" />
<source type="image/webp" srcset="photo.webp" />
<img src="photo.jpg" alt="照片" />
</picture>
浏览器从上到下检查,加载第一个它支持的格式。如果都不支持,就用 <img> 的 JPEG 版本。
Tip把最优格式放前面,兼容性最差的放最后。这样现代浏览器加载小文件,老浏览器也有保底。
为什么不用 CSS 或 JavaScript?
你可能会想:用 JavaScript 检测屏幕宽度,然后动态改 src 不就行了?
问题在于浏览器会预加载图片——在 CSS 和 JavaScript 执行之前就开始下载了。等你 JS 判断完该加载小图,大图已经下载完了,白浪费流量。
srcset 和 <picture> 是浏览器原生支持的,能在解析阶段就做出最优选择。
实战示例
一个完整的响应式图片方案:
<picture>
<!-- 小屏:竖向裁剪 + WebP -->
<source
media="(max-width: 600px)"
type="image/webp"
srcset="hero-mobile.webp" />
<source
media="(max-width: 600px)"
srcset="hero-mobile.jpg" />
<!-- 大屏:宽幅 + WebP -->
<source
media="(min-width: 601px)"
type="image/webp"
srcset="hero-desktop.webp" />
<source
media="(min-width: 601px)"
srcset="hero-desktop.jpg" />
<!-- 后备 -->
<img src="hero-desktop.jpg" alt="首页大图" />
</picture>
响应式图片速查
| 场景 | 方案 |
|---|---|
| 同图不同尺寸 | srcset + w 描述符 + sizes |
| 同图不同分辨率 | srcset + x 描述符 |
| 不同裁剪/构图 | <picture> + <source media=""> |
| 不同格式 | <picture> + <source type=""> |
下一节学习原生懒加载——让图片滚动到视口时才加载。