直接用+prefers-color-scheme即可原生实现暗黑模式图像自动切换:通过和分别指定深浅色图,提供必需后备,语义化、无js、高可访问性。

直接用 <picture></picture> + prefers-color-scheme 就能实现,无需 JS,且语义正确、可访问性好。
为什么不用 CSS background-image 切换图片
CSS 的 background-image 配合 @media (prefers-color-scheme: dark) 确实轻量,但它不适用于需要语义化、可缩放、响应式加载或无障碍支持的场景。比如 logo、图标、关键内容图——这些必须是 <img> 元素,才能被屏幕阅读器读出 alt 文本,才能被搜索引擎索引,才能在禁用 CSS 时正常降级显示。<picture></picture> 是为此类图像设计的唯一标准方案。
<picture></picture> 中 media="(prefers-color-scheme: dark)" 怎么写
核心就是两个 <source></source> 按顺序匹配,再加一个必需的 <img> 后备:
<picture><source media="(prefers-color-scheme: dark)" srcset="icon-dark.svg"><source media="(prefers-color-scheme: light)" srcset="icon-light.svg"> @@##@@ </source></source></picture>
-
media属性必须写全括号和引号,值区分大小写:dark不是Dark - 匹配顺序从上到下,第一个满足条件的
<source></source>生效,其余跳过 -
<img src="icon-light.svg" alt="网站标识">的src不能省略,也不能为空或#;它既是后备,也是最终渲染载体 - 若系统未设置偏好(
no-preference),所有<source></source>都不匹配,直接回退到<img>
常见“写了但不切换”的原因
不是语法错,而是环境或细节没对齐:
- 浏览器版本太旧:Safari 12.1+、Chrome 76+、Firefox 96+ 才完整支持;旧版 Safari 可能只识别
light或完全忽略 -
<img>缺少alt—— 某些浏览器(如旧版 Edge)在加载失败时只显示alt,而空alt会导致图标不可见 -
srcset写了路径但文件 404,浏览器静默失败,回退到<img>,你以为没切,其实是暗色图根本没加载成功 - 本地开发用
file://协议打开 HTML:部分浏览器(尤其是 Safari)会禁用prefers-color-scheme检测,必须走http://或https://(哪怕本地 server)
如何兼顾响应式尺寸和暗黑模式
srcset 和 media 可以共存,互不干扰:
<picture><source media="(prefers-color-scheme: dark)" srcset="logo-dark.png, logo-dark@2x.png 2x"><source media="(prefers-color-scheme: light)" srcset="logo-light.png, logo-light@2x.png 2x"> @@##@@ </source></source></picture>
- 每个
<source></source>的srcset独立解析,2x仅作用于该颜色方案下的高倍图 - 不要试图在一个
srcset里混写深浅图,srcset不解析颜色逻辑 - 如果还要适配屏幕宽度(如
media="(max-width: 768px)"),可以叠加多个<source></source>,但注意优先级:先宽度假设,再颜色假设,最后回退到<img>
真正容易被忽略的是:用户手动切换主题后,<picture></picture> 仍只响应系统偏好,不会跟着你加的 data-theme 或 .dark class 变。如果页面有手动开关,且你希望图片也同步切换,就得用 JS 监听并重写 <img src="logo-light.png" alt="品牌标识"> 的 src——但这已脱离 <picture></picture> 的设计初衷,属于权衡取舍。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











