真正可用的失败提示必须视觉可见、尺寸可控、语义明确且不依赖JS;推荐用<picture>内嵌高可用<img src="/assets/placeholder.svg">兜底,配合onerror="this.src='/assets/placeholder.svg';this.onerror=null;"及CSS背景+宽高防抖动。

图片加载失败时,仅靠 alt 文字撑不住体验——它不显示、不占位、不防布局抖动。真正可用的“失败提示”,必须是视觉可见、尺寸可控、语义明确的降级内容,且不能依赖 JS 才生效。
用 <picture> + 可靠 <img> src 做强制兜底
<picture> 本身不保证降级成功:所有 <source> 失败后,浏览器仍会尝试加载内部 <img>;如果这个 <img> 的 src 也 404,最终只显示 alt,空白一片。
- 必须把
<img>的src指向一个**高可用资源**,比如 CDN 上的占位图(/assets/placeholder-200x150.svg)或业务静态图 - 避免写
<img src="">或<img src="broken.jpg">—— 这等于主动放弃兜底 -
alt要写实义描述,例如alt="产品主图不可用",而不是"图片"或空字符串 - 服务端可配合 Nginx 对
/img/.*\.jpg404 返回带文字的占位图:https://cdn.example.com/missing.png?text=logo+404
内联 onerror 必须带 this.onerror=null
只写 onerror="this.src='fallback.png'" 是危险操作——fallback 图再失败,就会无限循环触发,页面卡死或内存暴涨。
- 稳定写法只有一种:
onerror="this.src='/assets/placeholder.svg'; this.onerror=null;" - fallback 路径推荐用绝对路径(
/assets/...)或 base64 data URL,避开相对路径在嵌套路由下的解析错乱 - 别信
srcset里的 fallback:浏览器不会因srcset失败而自动跳到onerror,它只响应最终渲染的<img>或<source>加载失败 - 注意:空
src、src=" "、CORS 阻塞都不会触发onerror,它只管“发了请求但返回非 2xx”
用 CSS :has() + background 做无 JS 视觉提示
当 JS 不可用(断网、拦截器、老 WebView)时,onerror 彻底失效。此时纯 CSS 方案能守住底线视觉。
立即学习“前端免费学习笔记(深入)”;
- 给容器设背景图:
div.img-container { background: #f5f5f5 url(/assets/placeholder.svg) center/contain no-repeat; } - 图片正常加载后自然覆盖背景;失败时背景始终可见,且不依赖任何事件
- 搭配
aspect-ratio或显式width/height,防止塌陷抖动 - 局限:无法知道是否真失败,
alt文字也不会显示,适合卡片封面等语义要求不高的场景
最容易被忽略的是:所有降级方案都假设你已控制了路径基准。本地双击打开 HTML 时 file:// 协议下,/assets/ 会指向系统根目录而非项目目录——开发阶段就该统一用 ./assets/ 或构建时注入正确前缀。



















