<picture> 标签仅在初始 HTML 解析时执行一次 <source> 匹配,不响应视口变化、DPR 切换或 JS 动态修改;禁止嵌套、<source> 必须合法 media 查询且 type 严格匹配 Content-Type,<img> 为必需子节点且不可省略 src 与 alt。

picture标签不支持嵌套或动态条件更新
浏览器只在初始 HTML 解析阶段执行一次 <source> 匹配,不会监听后续视口变化、DPR 切换或 JS 修改。你不能用 JS 动态插入 <source> 并期望它立即生效;也不能把 <picture> 套在另一个 <picture> 里——语法上不合法,解析时会被忽略或截断。
常见误操作包括:
- 用
document.createElement('source')创建后 append 到<picture>→ 浏览器已结束资源选择流程,新<source>被跳过 - 在 resize 事件里重写整个
<picture>innerHTML → 可能触发重复加载,且破坏语义和可访问性 - 把
<picture>放进<template>或 Shadow DOM 未激活时渲染 →<source>的 media 查询可能无法正确计算
media 属性只能写在 <source> 上,且必须是合法媒体查询
media 属性写在 <picture> 标签上(如 <picture media="(max-width:768px)">)完全无效,浏览器静默忽略。它只对 <source> 生效,且值必须是标准 CSS 媒体查询语法。
这些写法都会导致该 <source> 被跳过:
立即学习“前端免费学习笔记(深入)”;
-
media="max-width: 768px"→ 缺少括号,应为media="(max-width: 768px)" -
media="768px"或media="tablet"→ 非法媒体特征,不被识别 -
media="(min-width: 768px) and (orientation: landscape)"→ 合法,但部分旧 Android WebView 不支持 orientation
type 属性严格校验 MIME 类型,错一位就失效
type 是硬性匹配:浏览器看到 type="image/webp",就会检查服务器返回的 Content-Type 响应头是否**完全一致**(大小写、拼写、空格都不能差)。哪怕返回的是 image/webp (末尾多一个空格),或 image/webp;charset=utf-8,该 <source> 就被丢弃,不报错也不 fallback 到下一条。
调试时注意:
- Network 面板里看对应
<source>请求的响应头,确认Content-Type字段值 -
type="webp"、type="image/jpg"、type="image/avif "(带空格)全都不合法 - 推荐组合:
<source type="image/avif">+<source type="image/webp">+<source type="image/jpeg">+<img src="fallback.jpg">
<img> 不是装饰,漏掉或写错会直接白屏
<img> 是 <picture> 的强制子节点,不是可选补充。它必须存在、必须闭合、必须含 src 和 alt,且不能自闭合(<img /> 在 Safari 和部分 iOS 版本中不渲染)。
容易被忽略的细节:
-
<img alt="描述">没有src→ 整个区域空白,Network 面板里看不到任何图片请求 -
<img src="missing.jpg">返回 404 → 所有设备都显示破损图标,而不是尝试下一个<source> - 没写
alt→ 无障碍失败,部分合规检查工具直接报错 - 在
<img>上漏掉sizes,而只在<source>上写 →sizes被忽略,浏览器按默认100vw计算,小屏也可能加载大图
<picture> 就退化成一张静态图。



















