color-scheme 必须与 <meta name="color-scheme"> 配对使用才生效:<meta> 需静态写在 <head>,且 color-scheme: light dark 必须写在 html 元素上;否则原生控件(如 <input>、滚动条)不会自动适配暗色模式。

color-scheme 必须和 标签配对使用才生效
单独在 CSS 里写 color-scheme: light dark,原生表单控件(<input>、<select>、<progress>、滚动条 thumb)完全不会变色——浏览器根本不认你支持暗色模式。
硬性条件有两个,缺一不可:
-
<meta name="color-scheme" content="light dark">必须静态写在<head>里,不能用 JS 动态插入 -
color-scheme: light dark必须写在html元素上,写在body或某个 class 上,安卓 WebView 和部分 Safari 版本会失效
这个 <meta> 是 UA 渲染逻辑的“开关”,color-scheme 是“说明书”。漏掉任一,<input> 背景永远是白的,::-webkit-scrollbar-thumb 永远是浅灰。
@media (prefers-color-scheme: dark) 只改你的 CSS,不碰系统控件
很多人写了媒体查询但表单还是白底,误以为媒体查询失效。其实它工作正常,只是它只影响你写的样式,对 Canvas、CanvasText 这类系统语义色毫无作用。
立即学习“前端免费学习笔记(深入)”;
正确分工是:
-
@media (prefers-color-scheme: dark)用来覆盖你自定义的变量、文字颜色、背景、边框等 -
color-scheme + <meta>才能触发浏览器用系统语义色重绘原生控件
例如想让 <input> 在暗色下自动变深,光靠 background-color: #1a1a1a 是错的;应该留空,靠 color-scheme 让 UA 自动填 Canvas,再配合 color: CanvasText 保证可读性。
变量定义必须有默认值,否则浅色系统下可能白屏
如果只在 @media (prefers-color-scheme: dark) 里定义 --bg: #121212,而 :root 里没声明 --bg,那么浅色系统下 var(--bg) 会 fallback 到 unset,导致 background-color: var(--bg) 实际为 transparent —— 页面白屏或透出底层背景。
安全写法是:
- 先在
:root声明所有变量,默认值为浅色方案(如--bg: #fff) - 再在媒体查询中仅覆盖值(
--bg: #121212),不要重复声明其他无关属性 - 变量名必须严格一致,大小写、连字符都不能错,否则
var(--bg)不会取到新值
别把变量全堆在 :root。组件级变量建议就近定义,比如 .card { --card-bg: var(--bg); },再在媒体查询里重置 .card 的局部变量,避免全局污染。
SVG 图标和滚动条需要显式绑定变量
color-scheme 不会让 SVG 自动反色。如果你用 <svg><path fill="#333"></svg>,它在暗色下还是黑的。必须显式绑定:
- 用
fill: var(--icon-fill),并在媒体查询中更新--icon-fill - 或统一用
fill: currentColor,再控制父元素的color值
滚动条同理:color-scheme 不改 ::-webkit-scrollbar-thumb 颜色。得手动写:
::-webkit-scrollbar-thumb {
background: var(--scroll-thumb);
}
且 --scroll-thumb 的值也得在 @media (prefers-color-scheme: dark) 中覆盖,不能指望它自动适配。


















