<picture> 的优雅取决于 <source> 排序逻辑、属性精简及语义清晰度:格式优先时按 type 从高到低(AVIF→WebP→JPEG),布局优先时按 media 从大到小(桌面→平板→手机),<img> 为必填兜底项且需真实 src 与 alt。

picture 标签本身不决定“优雅”,真正影响可读性的是 <source> 的排列逻辑、属性精简程度,以及是否把语义意图清晰暴露给后续维护者。
按设备能力分层:先格式后布局
当你要同时支持 WebP 和 JPEG,并在不同屏幕用不同构图时,<source> 的顺序不是随便排的——浏览器只认「第一个匹配项」,所以得把高优先级条件放上面。
- 格式优先场景(如 WebP → AVIF → JPEG):把
type="image/avif"放最顶,再跟type="image/webp",最后才是带media的 JPEG 回退 - 布局优先场景(如桌面横幅 → 平板居中 → 手机竖版特写):按视口从大到小排,
media="(min-width: 1200px)"→media="(min-width: 768px)"→media="(max-width: 767px)" - 别混写
type和media在同一行还指望它“智能叠加”——浏览器只判断「是否同时为真」,不推理
缩进与换行要体现决策树结构
把每个 <source> 当作一个 if 分支,<img> 是 else 分支。这样写,人眼扫一眼就知道执行路径:
<picture> <source type="image/avif" srcset="hero-desktop.avif"> <source type="image/webp" srcset="hero-desktop.webp"> <source media="(min-width: 1200px)" srcset="hero-desktop.jpg"> <source media="(min-width: 768px)" srcset="hero-tablet.jpg"> <source media="(max-width: 767px)" srcset="hero-mobile.jpg"> <img src="hero-fallback.jpg" alt="首页主视觉"> </picture>
- 所有
<source>左对齐,<img>缩进一级,强调它是兜底项 - 每个
srcset只放一个路径(art direction 场景下),避免塞一堆w或x描述符干扰主干逻辑 - 删掉没用的空格和注释——比如
<!-- desktop -->这类注释,不如用属性本身说话
断点命名要能反推设计意图
别用裸数字写断点,比如 media="(max-width: 480px)" 看不出这是「iPhone SE 竖屏」还是「折叠屏窄态」。换成带语义的注释式写法:
立即学习“前端免费学习笔记(深入)”;
- 用 CSS 自定义属性模拟注释:
media="(max-width: 480px) /* iPhone SE */"—— 浏览器忽略注释部分,但人一眼看懂 - 或者直接用设计系统里的断点名(前提是团队共识):
media="(max-width: var(--breakpoint-sm))",需确保构建工具能展开 - 绝对不要写重叠断点,比如
(max-width: 768px)和(min-width: 768px)同时存在——768px 宽度时行为不可控,且后期改一个就得同步改另一个
img 标签不是装饰,是结构锚点
<img> 必须存在,且必须带 src 和 alt;它不是“备选”,而是整个 <picture> 的 DOM 锚点和无障碍基础。
- 漏掉或写成自闭合形式(
<img />)→ Safari 旧版本直接留白,Network 面板里连请求都不发 -
src路径必须真实可访问,404 不报错,只会静默 fallback 到空白区域 - 推荐给
<img>补上srcset和sizes,尤其当 fallback 图也要适配 2x 屏——否则 iPhone 用户可能加载 1x 图却显示模糊
最容易被跳过的,不是怎么写对,而是写完之后没打开 Network 面板确认:当前视口下,浏览器到底加载了哪一条 srcset?有没有因为单位漏写(768 而非 768px)导致整条 <source> 被跳过?这些细节,不查网络请求根本看不见。



















