source标签必须置于picture内,按从宽到窄顺序书写media条件,浏览器自上而下匹配首个满足的source并加载其srcset,全不匹配则回退至img的src;media值须为合法CSS媒体查询(如"(max-width: 768px)"),否则被静默忽略。

source 标签必须写在 picture 里,且顺序决定匹配优先级
<source> 不是独立可用的标签,它只在 <picture> 内部起作用。浏览器从上到下逐个检查每个 <source> 的 media 是否匹配,一旦为真,就加载它的 srcset,后面的 <source> 全部跳过。所以宽屏规则要放前面,窄屏兜底放后面。
常见错误是把小屏写在最前:<source media="(max-width: 480px)"> 放第一个,结果桌面用户也只加载小图——因为所有视口宽度都 ≤ 480px?不,但浏览器没继续往下看。
- ✅ 正确顺序示例:
min-width: 1200px→min-width: 768px→max-width: 767px - ❌ 错误顺序示例:
max-width: 767px→min-width: 768px→min-width: 1200px -
<source>之间不能有空元素、注释或文本节点干扰顺序
media 属性必须是合法 CSS 媒体查询,括号不能少
media 不是随便填个宽度数字就行。浏览器只认标准语法,缺括号、关键字或单位都会导致整个 <source> 被静默忽略——Network 面板里看不到请求,控制台也没报错,图片就直接 fallback 到 <img src>。
- ✅ 正确写法:
media="(max-width: 768px)"、media="(min-width: 1440px) and (prefers-reduced-motion: reduce)" - ❌ 错误写法:
media="max-width: 768px"(缺括号)、media="768px"(非媒体查询)、media="screen and (max-width: 768px)"(冗余,<source>默认只用于屏幕) - 断点值要互斥:避免
(max-width: 768px)和(min-width: 768px)并存,768px 宽度会同时满足两个条件,但浏览器只取第一个,第二个永远不生效
srcset 在 source 中只管“提供选项”,不自动选图
<source> 的 srcset 是给浏览器列候选,不是命令它加载某张图。浏览器会结合当前设备 DPR、视口宽度、sizes 属性(如果写了),再决定加载哪一项。你写 srcset="a.jpg 1x, b.jpg 2x",不代表 Retina 屏一定加载 b.jpg——如果页面里这张图只显示 200px 宽,而 b.jpg 是 1600w,它可能反而选更小的资源。
-
srcset支持两种语法:url 1x(按设备像素比)、url 400w(按固有宽度) - 用
w单位时,必须配合sizes属性,否则浏览器无法估算所需尺寸 -
<source>不支持src属性,写了也无效;只靠srcset+media(或type)驱动
type 属性用于格式降级,但依赖服务器 content-type
想让支持 AVIF 的浏览器加载 .avif,不支持的退到 .webp 或 .jpg,光靠文件后缀没用。type 是 MIME 类型开关,浏览器只信任服务器返回的 Content-Type 响应头是否匹配。
- ✅ 正确写法:
type="image/avif"、type="image/webp"、type="image/jpeg" - ❌ 错误写法:
type="avif"、type="webp"、type="jpg" - 如果 DevTools Network 面板里某个
<source>请求状态是(blocked:mime-type),八成是服务器没配对的Content-Type - 多个
<source>按顺序排列,浏览器从上到下找第一个type匹配且media满足的项,找到就停
最容易被忽略的是:没有 <img> 就没有 fallback,整个 <picture> 区域会空白;<img> 的 src 必须存在,且最好也带 srcset 和 alt——它不是摆设,而是真实用户可能看到的最后一张图。


















