旧页面加了媒体查询也没变暗,是因为硬编码颜色值(如#fff)优先于变量且不在媒体查询内,导致深色模式失效;需将关键选择器的颜色属性替换为var()并确保变量有默认值。
@media (prefers-color-scheme: dark) 不会自动覆盖旧样式,必须显式重写所有用到的颜色、背景、边框等规则——否则旧 CSS 里硬编码的 #ffffff 或 black 仍会生效,深色模式形同虚设。
旧页面通常直接写死颜色值,比如 body { background: #fff; color: #000; }。即使你后来在 :root 里加了变量和 @media (prefers-color-scheme: dark),这些老规则依然优先匹配并应用,新变量根本没被用上。
body { background: #fff; } 比 body { background: var(--bg); } 更早、更具体,就赢了var(),自然不响应变量变更;也不在媒体查询里,所以不会随系统主题切换!important,覆盖难度更高核心不是改变量,而是把旧规则“转译”成变量驱动——重点是找到关键样式节点,最小化侵入式修改。
body、h1、.btn、.card、input 等,检查 DevTools 的 Styles 面板,看哪些声明带硬编码颜色var() 替换其 color、background、border-color、box-shadow 值,例如:body { color: var(--text-primary); background: var(--bg-primary); }
font-family、margin 这类无需动body[data-theme="auto"] { color: var(--text-primary) !important; }
旧页面可能跑在 Safari 12–14、Chrome 75 以下等不支持 prefers-color-scheme 的环境。不能只依赖媒体查询,得有 fallback 路径。
var(--xxx) 都有默认值::root { --text-primary: #333; },避免不支持时回退成透明或浏览器默认色color-scheme: light dark + <meta name="color-scheme" content="light dark">,否则 <input> 在 iOS Safari 下仍白底黑字body.dark),可保留该逻辑,把 @media 规则合并进对应 class 内,避免冲突:body.dark { --bg-primary: #121212; }
::-webkit-scrollbar、<progress> 轨道等 UA 控件必须单独写伪元素规则,且同样要用变量或系统语义色(如 Canvas)最容易被忽略的是:所有旧 CSS 里出现过颜色值的地方,只要它会影响明暗感知,就必须出现在变量体系中——漏掉一个 --border-color,就可能让卡片边框在深色下消失;漏掉一个 --icon-fill,SVG 图标就卡在黑色无法反色。