srcset本身不提供降级能力,仅做响应式资源选择;真正降级必须依赖真实可访问的src兜底(如JPG/PNG),否则srcset中任一候选404或失败即白屏,且浏览器不会自动切换至其他srcset项或格式。

srcset 本身不提供“降级”能力,它只做响应式资源选择;真正的降级必须靠 src 属性兜底,且这个 src 必须是真实可访问的 JPG/PNG。
为什么写了 srcset 还会白屏
浏览器加载 <img alt="HTMLWeb开发srcset降级实践教程" > 时,会先尝试从 srcset 列表中选一个最匹配的资源(按设备像素比或视口宽度),但一旦该资源返回 404、CORS 拒绝、MIME 错误或解码失败,它不会自动 fallback 到列表里另一个 srcset 项,更不会退到其他格式——它只会静默失败,最终渲染空白或破损图标。
-
srcset不是备用路径池,而是同一格式下的候选集(比如全是.jpg) - 若你写
srcset="a@2x.jpg 2x, a@1x.jpg 1x",而a@2x.jpg404,浏览器不会去加载a@1x.jpg - 缺少
src属性,或src指向无效地址(如空字符串、#、不存在的placeholder.png),就会直接白屏 - IE11 及更老浏览器完全忽略
srcset,全靠src活命
srcset + sizes 必须配对使用
不写 sizes,srcset 在多数现代浏览器中会退化为按 100vw 加载最大图,浪费带宽且极易超时失败。浏览器需要 sizes 告诉它“这张图在不同断点下实际占多宽”,才能提前预加载合适尺寸。
- 正确写法:
sizes="(max-width: 480px) 100vw, (max-width: 768px) 50vw, 33vw" - 错误写法:
sizes="(max-width: 480px) 100%"(百分比无效,必须是vw、px或em) - 如果图在 CSS 中被设为
width: 100%; max-width: 300px,但sizes写了100vw,浏览器会错估尺寸,加载过大资源 - 服务端渲染(SSR)时,
sizes值必须与客户端 CSS 实际生效的布局一致,否则首屏加载错位
srcset 和 picture 的分工边界
srcset 解决的是“同一格式下如何选最合适分辨率/密度的图”,<picture></picture> 才解决“不同格式之间的优先级切换”。混用或错放会导致降级链断裂。
立即学习“前端免费学习笔记(深入)”;
- 想用 WebP → 回退 JPEG?必须用
<picture></picture>,把type="image/webp"放<source></source>里,<img src="fallback.jpg" alt="HTMLWeb开发srcset降级实践教程" >作最终兜底 - 把 WebP 地址塞进
srcset却不配<picture></picture>:Safari ≤13.1、旧 Android WebView 直接不发请求,留白 -
<source srcset="small.jpg 480w" sizes="..."></source>是合法的,但它仍属于格式内响应式,不是跨格式降级 -
<img srcset="logo.avif" src="logo.jpg" alt="HTMLWeb开发srcset降级实践教程" >是无效写法:AVIF 不会被识别,src是唯一 fallback,但用户永远得不到 AVIF 加速
onerror 补救要防死循环和时机错位
监听 onerror 是最后防线,但它发生在浏览器已发出请求并确认失败之后,用户已经看到空白。此时补救的关键是快、稳、可控。
- 内联写法最可靠:
onerror="this.src='/img/fallback.svg'; this.onerror=null",立即解绑避免重入 - 不要在
onerror中再加载未压缩大图或带查询参数的动态 URL(如?x-oss-process=) - 若 fallback 图也失效,会再次触发
onerror;加 guard 条件:if (!this.src.includes('fallback')) this.src='...' - 动态插入的
<img alt="HTMLWeb开发srcset降级实践教程" >元素,onerror必须在appendChild()前绑定,否则首次错误捕获不到 - 慎用
loading="lazy"配合onerror:懒加载延迟发起请求,失败感知滞后,体验更差
真正容易被忽略的一点:所有降级路径上的资源(src、srcset 中每个 URL、<picture></picture> 里每个 srcset、onerror 中的 fallback 地址)都必须能在浏览器地址栏单独打开并返回 HTTP 200 + 正确 Content-Type。少一个可用,整条链就断在那儿。



















