html5 标签配合 prefers-color-scheme 媒体查询可原生实现暗黑模式图片自动切换:通过 和 分别指定深浅色图, 提供必需后备,语义化、无 js、高可访问性。

picture 标签怎么配合 prefers-color-scheme 切换图片
直接用 <picture></picture> 实现黑暗模式图片切换,核心不是靠 JS 监听主题变化,而是靠 CSS 媒体查询 + <source></source> 的 media 属性。浏览器原生支持,无需 JS,兼容性也够用(Chrome 38+、Firefox 65+、Safari 14+)。
关键点:每个 <source></source> 通过 media="(prefers-color-scheme: dark)" 或 media="(prefers-color-scheme: light)" 指定对应主题下的图片源,<img> 作为 fallback(必须有,否则不渲染)。
<picture><source srcset="logo-dark.png" media="(prefers-color-scheme: dark)"><source srcset="logo-light.png" media="(prefers-color-scheme: light)"> @@##@@ </source></source></picture>
-
srcset可以写单图,也可以写响应式多分辨率(如"logo-dark@2x.png 2x"),但注意:每个<source></source>的srcset独立生效,不跨 source 共享 - 顺序重要:
<source></source>从上到下匹配,第一个满足media条件的生效,其余跳过;所以建议把dark放前面或按逻辑优先级排 - 如果用户系统未开启深色模式(即
prefers-color-scheme为no-preference),所有<source></source>都不匹配,最终回退到<img src="logo-light.png" alt="Logo">的src
为什么 img 的 src 不能省略
<picture></picture> 本身不渲染内容,它只是个容器;真正负责显示的是内部的 <img>。没有 <img>,哪怕所有 <source></source> 都匹配成功,页面也不会显示任何图片——这是常见空白 bug 的根源。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
-
<img>的src是必需属性,即使你写了两个<source></source>覆盖了 light/dark 场景,仍需提供一个可用的src -
<img>的alt也要写,否则无障碍访问会失败,且部分浏览器在加载失败时只显示alt文本 - 可以复用某个
<source></source>的图作为<img>的src(比如 light 图),但不能留空或写src="#"
遇到图片不切换?先查这三件事
常见“写了但没切”问题,基本不出现在逻辑上,而出现在环境或细节配置里:
- 检查系统设置:macOS / Windows / iOS 是否真开启了深色模式?浏览器是否继承系统(Chrome 和 Firefox 默认继承,Edge 有时需手动开「跟随系统」)
- 确认
<source></source>的media值拼写准确:prefers-color-scheme中间是短横线,不是下划线,且大小写敏感(全小写) - 打开 DevTools → Elements → 点击
<picture></picture>,右键「Reveal in Elements panel」,再看右侧 Styles 面板里是否显示当前生效的<source></source>—— 如果没高亮,说明媒体查询没命中,可能是系统未启用或浏览器不支持
需要适配 Windows 高对比度模式或强制颜色方案怎么办
仅靠 prefers-color-scheme 不足以覆盖所有可访问场景。prefers-reduced-motion 或 forced-colors 是另一类独立信号,但它们和深色模式不互斥。如果你的应用要满足 WCAG,得额外考虑:
-
forced-colors: active表示用户启用了高对比度模式(如 Windows 设置里的「高对比度主题」),此时图片可能被系统覆盖或禁用,建议搭配color-scheme: light dark声明文档支持范围 - 目前无法用
<picture></picture>直接响应forced-colors,只能靠 JS 动态替换,或者接受系统接管——这不是 bug,而是辅助技术的设计预期 - 若必须提供高对比度专用图,推荐用
@media (forced-colors: active)+ CSS background-image 控制,而非<picture></picture>
深色模式图片切换本身很简单,但容易卡在「以为写了就生效」这个点上。最常被忽略的是:系统没开深色模式、<img> 缺失、或者误以为 <picture></picture> 自己能渲染。实际只要三要素齐——<source></source> 带对 media、<img> 有 src、系统真处于对应模式——它就自动工作。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










