用 CSS 变量与 prefers-color-scheme 做一键深色模式:一次学习笔记

举报
yd_298459565 发表于 2026/11/06 09:08:35 2026/11/06
【摘要】 最近给自己的小工具页面加深色模式,顺手把做法整理成这篇笔记。目标很简单:亮色和深色只维护一套样式,切换时不改结构、不重写颜色,用户的选择还要能记住,下次打开仍然生效。一、先把颜色收进 CSS 变量以前写页面,颜色散落在各个选择器里,改一套主题就要逐行替换。现在的做法是把全部语义颜色集中定义在 :root 里,例如背景、文字、卡片、边框和主色各一个变量,组件只引用变量,不写死色值。切换主题时,...

最近给自己的小工具页面加深色模式,顺手把做法整理成这篇笔记。目标很简单:亮色和深色只维护一套样式,切换时不改结构、不重写颜色,用户的选择还要能记住,下次打开仍然生效。


一、先把颜色收进 CSS 变量


以前写页面,颜色散落在各个选择器里,改一套主题就要逐行替换。现在的做法是把全部语义颜色集中定义在 :root 里,例如背景、文字、卡片、边框和主色各一个变量,组件只引用变量,不写死色值。切换主题时,只需要换掉这一组变量的值,页面其余样式完全不动,维护成本立刻降下来。


二、用 prefers-color-scheme 跟随系统


浏览器提供了 prefers-color-scheme 媒体查询,可以读到用户系统的亮色或深色偏好。在 CSS 里写一段 @media (prefers-color-scheme: dark),在其中重定义同一组变量,页面第一次打开就能自动贴合系统设置,不用用户先手动点一次。这一步只做默认值,不做强制记忆。


三、手动切换:给 html 加一个属性


自动跟随系统还不够,用户常常想在网页里自己选。做法是在 html 元素上放一个 data-theme 属性,取值为 light 或 dark,CSS 里用 html[data-theme="dark"] 覆盖变量。点击切换按钮时,用 JavaScript 在 light 和 dark 之间翻转这个属性,同时把结果写进 localStorage。下次打开页面,先读 localStorage,有保存值就用保存值,没有才跟随系统。


四、切换时避免闪烁的两个细节


第一个细节是脚本要尽早执行:读取 localStorage 并设置 data-theme 的小段脚本放在 head 里、样式之前执行,避免页面先以亮色闪一下再变深色。第二个细节是给颜色加过渡:对 background-color 和 color 加一个 0.2 秒左右的 transition,切换看起来是平滑渐变,而不是生硬跳变。过渡时间不宜太长,否则每次切换都像在等待。


五、一个最小可用的示例


:root { --bg: #ffffff; --text: #1f2937; --card: #f3f4f6; --accent: #2563eb; }

@media (prefers-color-scheme: dark) { :root { --bg: #111827; --text: #f9fafb; --card: #1f2937; --accent: #60a5fa; } }

html[data-theme="dark"] { --bg: #111827; --text: #f9fafb; --card: #1f2937; --accent: #60a5fa; }

body { background: var(--bg); color: var(--text); }


切换按钮的逻辑只有三行:读当前属性、翻转、保存。localStorage 的键名可以固定,例如 theme。需要注意的是,手动选择应当优先于系统偏好,只有当用户点击“跟随系统”时才清除保存值。


六、学习小结


这次练习的关键收获有三点:第一,颜色要先语义化再谈主题,变量名表达的是用途而不是色值;第二,系统偏好只决定默认值,用户的显式选择永远优先;第三,体验细节决定成败,尽早设置主题和加短过渡,能避免最常见的闪烁问题。下一步想试试把这套变量扩展到图表和代码块配色上,让深色模式覆盖更完整。


以上为个人学习记录,示例代码均为自行编写的最小演示,可直接在空白 HTML 文件中验证。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。