prefers-color-scheme 媒体查询必须作用于 :root 才能覆盖主题变量,写在 .card 或 body 内无效;所有变量须先在 :root 定义默认值,再于 @media (prefers-color-scheme: dark) { :root { ... } } 中统一覆盖,同时声明 color-scheme: light dark 以适配原生控件。

prefers-color-scheme 媒体查询必须写在 :root 下才能生效
直接在 .card 或 body 里写 @media (prefers-color-scheme: dark) { color: #333; } 是无效的——浏览器不会把媒体查询里的样式“提升”到根作用域,导致 CSS 变量无法被覆盖。正确做法是把所有颜色变量定义在 :root,再用媒体查询统一改值:
-
:root中定义默认(浅色)变量,如--color-text: #1a1a1a; -
@media (prefers-color-scheme: dark)块必须也作用于:root,否则变量不更新 - 不能写成
body@media {...}或.theme-dark @media {...},语法错误且无效果
别用 #000000 当深色背景,hsl() 更可控
纯黑背景在 OLED 屏上会发灰、文字边缘虚化,而且与浅色模式的 #ffffff 对比过猛。推荐用 hsl(210, 10%, 12%) 这类带微光的深灰,好处是:
- 保持色相一致,避免浅色蓝主色切到深色后变成“脏紫”
- 亮度(
l)可精确控制:浅色文字用hsl(210, 10%, 92%),确保对比度 ≥ 4.5:1 - 所有浏览器都支持静态
hsl(),但不支持calc()动态计算,所以必须手动算好值
color-scheme 属性不是摆设,它管滚动条和表单控件
只写 @media (prefers-color-scheme: dark) 改背景和文字,却漏掉 color-scheme: light dark,会导致深色模式下滚动条还是亮白、<input> 边框刺眼。这个属性的作用很实在:
- 加在
:root或html上,一行就够了:color-scheme: light dark; - 它让浏览器自动调整
::-webkit-scrollbar、<select></select>下拉箭头、<button></button>默认边框等原生元素 - 旧版 Safari 需要
-webkit-appearance: none配合,但现代版本已无需 hack
CSS 变量命名要带语义,别用 dark-xx 这类描述性前缀
写 --dark-bg 或 --light-text 看似直观,实际会让维护崩溃——变量名里塞了“状态”,一旦未来加第三种主题(比如 sepia),就得全量重命名。应该:
- 用功能/层级命名:
--color-bg-primary、--color-border-subtle - 所有变体都在同一作用域覆盖,靠媒体查询或
html.dark类切换值 - 避免在变量里写透明度(如
rgba(0,0,0,0.1)),暗色下多层叠加容易发灰;改用独立的--opacity-20控制
#e0e0e0 的边框,在 #121212 背景上几乎看不见,必须单独调高亮度,而不是复用文本色变量。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











