必须用 的场景是构图切换(如桌面全景/手机特写)和格式兜底(如 avif → webp → jpeg),仅缩放时用 更轻量高效。

什么时候必须用 <picture></picture> 而不是 <img srcset>
卡片组件里图片内容随设备尺寸变化时,<picture></picture> 才不可替代。比如:
- 桌面端展示完整产品全景图,移动端只保留人物脸部特写(构图完全不同)
- 横屏平板用宽幅 banner 图,竖屏手机切为紧凑头像+文字组合图
- 需要优先加载
image/avif,但 Safari 16.4 之前不支持,得 fallback 到image/webp或image/jpeg
如果只是同一张图缩放显示(比如商品图始终居中裁剪),<img srcset="a.jpg 400w, b.jpg 800w" sizes="(max-width: 768px) 100vw, 50vw"> 更轻、兼容更好、浏览器选择更智能。
<source></source> 的 media 属性必须从宽到窄写
浏览器按顺序匹配,遇到第一个 media 为 true 就停,不会继续判断。写反了会导致高分辨率设备加载低清图。
✅ 正确顺序:
<source media="(min-width: 1200px)" srcset="card-desktop.jpg"><source media="(min-width: 768px)" srcset="card-tablet.jpg"><source media="(max-width: 767px)" srcset="card-mobile.jpg"></source></source></source>
❌ 错误写法(小屏永远卡在第一条):
<source media="(max-width: 767px)" srcset="card-mobile.jpg"><source media="(min-width: 768px)" srcset="card-tablet.jpg"></source></source>
⚠️ 边界重叠也要小心:(max-width: 768px) 和 (min-width: 768px) 在 768px 宽度时行为不确定,建议用 (max-width: 767px) / (min-width: 768px) 明确分隔。
<img> 不是可选的,且必须带 src 和 alt
<picture></picture> 本身不渲染任何内容,所有图片都靠内部的 <img> 显示。漏掉它,或只写 <img alt="..."> 没有 src,卡片区域就是空白。
常见错误:
-
<img>或<img>—— 自闭合或无结束标签,部分旧版 Safari 渲染失败 -
<img src="" alt="...">—— 空src触发 404 请求,影响性能监控 -
<img src="fallback.jpg">但没写alt—— 违反无障碍要求,可能被 Lighthouse 报错
推荐写法:<img src="card-mobile.jpg" alt="卡片主视觉:蓝色耳机特写" style="max-width:90%" style="max-width:90%">,加上宽高属性还能防止布局偏移(CLS)。
type 属性必须放在前面,且依赖服务器 MIME 配置
想用 WebP 或 AVIF 提效,不能只靠 type="image/webp"。浏览器看到不支持的 type 就跳过该 <source></source>,不会尝试下一个。
所以顺序很重要:
<source type="image/avif" srcset="card.avif"><source type="image/webp" srcset="card.webp"><source type="image/jpeg" srcset="card.jpg"></source></source></source>
但前提是服务器对 .avif 文件返回 Content-Type: image/avif,否则 Chrome 会拒绝加载——即使写了 type,也白搭。
本地开发时容易忽略这点:Webpack/Vite 默认不配 AVIF MIME 类型,Nginx/Apache 也需要手动加配置。没配好,type 就形同虚设。
<picture></picture> 当成“高级配置”硬套,结果维护三套图源却只换来 5% 的流量节省,还拖慢 CI 构建。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











