theme-color 无法通过 css 媒体查询控制,必须用 js 在 dom 加载早期读取系统偏好或 localstorage 并手动设置 meta 标签 content 属性,且需在 pwa 首屏前执行以确保 android 地址栏正确响应。

直接用 <meta name="theme-color"> 配合 @media (prefers-color-scheme: dark) 是无效的——theme-color 不响应 CSS 媒体查询,也不能通过 JS 动态改写后立即生效(尤其在 PWA 安装后)。必须靠 JS 主动切换,并手动同步到 meta 标签。
为什么 @media 无法控制 theme-color
theme-color 是 HTML 元素属性,不是 CSS 变量,浏览器不把它当作样式处理。写在 @media 块里的 <meta> 标签不会被解析或替换,只会被忽略。实测中,以下写法完全无效:
<style>
@media (prefers-color-scheme: dark) {
meta[name="theme-color"] { content: "#121212"; } /* ❌ 无作用 */
}
</style>
正确做法:JS 初始化时读取偏好并写入 <meta>
必须在 DOM 加载早期(最好在 内联脚本中)完成三件事:查 localStorage → 查 matchMedia → 设置 <meta name="theme-color"> 的 content 属性。
- 优先级:localStorage > 系统偏好 > 默认值(如
#ffffff) - 设置时机:必须在
<meta>标签存在后执行,不能等DOMContentLoaded,否则 Android Chrome 可能已按旧值渲染地址栏 - 注意:PWA 安装后首次加载,
theme-color会缓存,需确保 JS 在首屏前执行
示例(放在 最上方):
<script>
const saved = localStorage.getItem("theme");
const isDark = saved === "dark" ||
(!saved && window.matchMedia("(prefers-color-scheme: dark)").matches);
<p>const themeColor = isDark ? "#121212" : "#ffffff";
document.querySelector('meta[name="theme-color"]').content = themeColor;
</script>
手动切换时必须同步更新 theme-color
用户点按钮切主题,只改 data-theme 不够——theme-color 不会自动变,地址栏/书签栏颜色仍卡在旧值。
- 每次调用
document.documentElement.dataset.theme = "dark"后,必须紧接着更新<meta name="theme-color"> - 不要用
document.head.appendChild()替换整个 meta 标签,会导致 Safari 下部分机型失效 - 推荐复用已有 meta 元素:
document.querySelector('meta[name="theme-color"]').content = "#121212" - 如果页面有多个
theme-colormeta(比如不同设备适配),需明确选中对应的那个
Android 和 iOS 的实际表现差异
theme-color 在不同平台行为不一致,容易误判“已生效”:
- Android Chrome:支持
theme-color,且会响应 JS 修改(需刷新后才稳定,但热切换基本可用) - iOS Safari:完全忽略
theme-color,无论 JS 怎么改都不生效;仅支持<meta name="apple-mobile-web-app-status-bar-style">控制状态栏,且仅限 PWA - PWA 安装后:Android 上首次安装时取的是 HTML 中初始
content值,后续 JS 修改只影响运行时,不影响桌面图标背景色
真正可控的只有 Android 浏览器地址栏,其他场景建议放弃依赖 theme-color 做视觉一致性保障——它从来就不是可靠的主题同步通道。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











