transition: --bg-color 0.3s无效,因CSS不支持直接过渡自定义属性;必须将transition写在基础选择器(如body)上,作用于background-color等原生可动画属性,且默认态与.dark态均需显式声明具体颜色值。

直接写 transition: --bg-color 0.3s 是无效的,浏览器会忽略它;平滑过渡必须作用在具体属性上,比如 background-color 和 color,且两端值都得是可插值的颜色。
为什么 transition 写在 .dark 类里会闪屏
浏览器只对「从一个明确值变到另一个明确值」的过程做插值动画。如果 transition 只出现在 .dark 规则中,那默认状态(浅色)下根本没有过渡声明,切换时第一帧就跳变——这就是首屏闪黑或闪白的根源。
- 必须把
transition声明写在基础选择器里,例如body或html - 所有参与过渡的属性(
background-color、color、border-color)都要在默认态和.dark态中写死具体值 - 避免一端用
transparent、inherit或initial,它们无法可靠插值
如何用 CSS 变量 + class 切换实现可控过渡
变量本身不触发重绘,但可以配合 :root 和 .dark 类统一管理颜色值。关键在于:过渡声明仍要落在使用变量的元素上,而不是变量定义处。
- 在
:root中定义变量:--bg-primary: #ffffff;,再在:root.dark中覆盖:--bg-primary: #121212; - 在
body上写:background-color: var(--bg-primary); transition: background-color 0.35s ease-in-out; - 切换必须调用
document.documentElement.classList.toggle('dark'),不是body或自定义data-theme - 若用
data-theme,CSS 选择器必须写成html[data-theme="dark"],不能写[data-theme="dark"] :root(语法非法)
初始化阶段最容易被忽略的三件事
90% 的闪屏问题出在 DOM 渲染前没准备好主题类,导致浏览器先按默认样式渲染一次,再重绘。
立即学习“前端免费学习笔记(深入)”;
- 必须在
<head>内联 JS 或DOMContentLoaded之前读取localStorage.getItem('theme')并立即设 class - 若同时支持系统偏好,需用
window.matchMedia('(prefers-color-scheme: dark)')同步判断,但仅作 fallback,不可替代用户手动选择 -
transition的时长建议控制在 300–450ms,ease-in-out比ease更柔和,适合主题切换这类全局变化
真正决定是否“丝滑”的,从来不是 JS 切换逻辑有多复杂,而是 CSS 是否在正确的位置、用正确的属性、写了正确的起止值——漏掉任意一环,就只剩跳变。


















