标签本身不切换图片,仅作容器;真正起作用的是内部规则与浏览器匹配逻辑,必须配对media与srcset、确保兜底存在且格式兼容。

<picture></picture> 标签本身不“切换图片”,它只是容器;真正起作用的是内部的 <source></source> 规则 + 浏览器的匹配逻辑。没配对的 <source></source> 或漏掉 <img> fallback,图片就直接不显示。
为什么 <source></source> 的 media 和 srcset 不能混用?
这是最常踩的坑:把 media="(min-width: 768px)" 和 srcset="small.jpg 1x, small@2x.jpg 2x" 放在同一个 <source></source> 里,浏览器会忽略整个 <source></source>。因为 media 是做“条件筛选”,srcset 是做“像素密度适配”,二者属于不同层级的决策逻辑。
正确做法是分层处理:
- 用多个
<source></source>分别定义不同视口宽度下的资源(靠media) - 每个
<source></source>内只用srcset+sizes处理同一宽度下的 DPR 适配 - 最后的
<img>必须有src和srcset,它是所有规则都不匹配时的兜底,且仍参与 DPR 选择
如何写 sizes 才能让 srcset 算对宽度?
sizes 不是“告诉浏览器图片多大”,而是“告诉浏览器:在不同断点下,这张图将占据视口的多少宽度”。如果写错,浏览器选错资源,高清屏上反而加载小图。
常见错误写法:sizes="100vw"(默认值,但实际布局中图片可能只占一半)
推荐写法(结合 CSS 布局):
<source media="(min-width: 1024px)" srcset="hero-1200w.jpg 1200w, hero-1600w.jpg 1600w" sizes="90vw"><source media="(min-width: 768px)" srcset="hero-800w.jpg 800w, hero-1200w.jpg 1200w" sizes="95vw"> @@##@@</source></source>
注意:sizes 值必须和真实 CSS 中该 <img src="hero-400.jpg" srcset="hero-400.jpg 400w, hero-800.jpg 800w" sizes="100vw" alt="hero"> 的宽度表现一致,否则 srcset 选源失效。
WebP / AVIF 图片怎么安全 fallback?
不是所有浏览器支持 type="image/webp",Chrome 和 Edge 支持,Safari 直到 16.4 才支持 AVIF。单纯靠 <source type="image/avif"></source>,老 Safari 会跳过所有 <source></source>,直接加载 <img> 的 src——但如果 <img> 的 src 指向的是 AVIF,那就挂了。
稳妥方案:
-
<source></source>优先放 WebP(兼容性更好),再放 AVIF(可选) <img> 必须是 JPEG/PNG 这类通用格式- 不要把
<img src>的src指向 WebP/AVIF,哪怕你认为“现在都支持了” - 想用 AVIF 又要保底?得靠 JS 检测或服务端 UA 判断,
<picture></picture>本身做不到
真正难的不是写对标签,而是让 sizes 和实际布局严格同步、让 fallback 路径在所有旧浏览器里都有图可载。改一个 CSS 宽度,很可能就要同步更新 sizes 和 srcset 列表。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











