标签本身不自动切换,需严格合规写法才能让浏览器在主题变化时重选替换图片:暗色必须在前且media语法完整,不可省略、须含src和alt。

<picture></picture> 标签本身不“自动切换”,它靠浏览器原生匹配机制在主题变化时重选并替换已渲染的图片——但前提是写法完全合规,否则 Safari 会忽略暗色规则、Chrome 可能回退到 <img> 的 src 而不是你期望的图。
source 顺序和 media 语法必须严格正确
暗色 <source></source> 必须放在亮色之前,且 media 值要带完整括号和引号:
-
media="(prefers-color-scheme: dark)"✅ 正确 -
media="prefers-color-scheme: dark"❌ 缺括号,Safari 和旧 Edge 直接跳过 -
media="(dark)"❌ 语法错误,所有浏览器都无视 - 顺序颠倒(亮色在前)→ Safari 15.4+ 仍可能只加载第一个匹配项,导致暗色永远不生效
img 标签不是可选后备,而是必需渲染节点
<picture></picture> 不渲染任何内容,真正显示图像的是内部的 <img>。漏掉它、写成自闭合 <img src="..." alt="...">、或把 src 设为空/占位符,都会导致页面空白。
-
src必须指向一个真实可用的图片(通常是亮色版,作为最宽兼容 fallback) -
alt必须存在且有意义,这是可访问性硬性要求 - 不能省略
<img>,哪怕你只想要暗色图——没有它,<picture></picture>就是空容器
多格式支持要按 type + media 组合写,不能混搭
想同时提供 WebP 和 JPEG,得为每种主题各写一组 <source></source>,而不是把两种格式塞进同一个 srcset:
<picture><source media="(prefers-color-scheme: dark)" srcset="logo-dark.webp" type="image/webp"><source media="(prefers-color-scheme: dark)" srcset="logo-dark.jpg" type="image/jpeg"><source media="(prefers-color-scheme: light)" srcset="logo-light.webp" type="image/webp"><source media="(prefers-color-scheme: light)" srcset="logo-light.jpg" type="image/jpeg"> @@##@@ </source></source></source></source></picture>
- 浏览器按顺序匹配:先找满足
media且支持type的<source></source> - WebP 优先,不支持时自动降级到 JPEG,与主题逻辑正交
- 不要把
type和media拆开写,否则可能触发错误 fallback
不支持 prefers-color-scheme 的浏览器怎么办
IE、旧版 Safari 或某些安卓 WebView 会直接跳过所有 <source></source>,只渲染 <img src="logo-light.jpg" alt="Logo">。这不是 bug,是规范行为。
- 确保
<img>的src是安全默认图(通常用亮色版) - 不需要 polyfill,也不该用 JS 动态插入
<source></source>—— 那会破坏语义和可访问性 - 如需额外控制“未指定主题”(
no-preference),可加一条:<source media="(prefers-color-scheme: no-preference)" srcset="logo-light.png"></source>,但它不是必需项
最容易被忽略的点:主题切换后图片没换,往往不是浏览器不支持,而是 <img> 缺 alt、<source></source> 的 media 少了括号、或者暗色 <source></source> 被放到了亮色后面——这三个问题占实际线上故障的 90% 以上。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











