能否合并@media与body.dark类规则以避免CSS代码重复问题?
合并规则方案
完全可以合并重复的暗色主题样式,以下是3种常用实现方案:
方案1:原生CSS新特性(无工具依赖)
使用CSS Level 4新增的media()条件配合:is()伪类,直接把两种触发暗色主题的场景合并为同一段规则,不需要重复写变量:
:root { --color: #000; --bg: #fff; --hover: #eee; } /* 合并后的暗色模式规则,同时匹配系统暗色偏好和手动加的dark类 */ :is(body.dark, :root:media(prefers-color-scheme: dark)) { --color: #fff; --bg: #000; --hover: #555; }
注意:该写法目前在Chrome 114+、Firefox 121+版本支持,需要兼容旧浏览器可以选下面两种方案。
方案2:预处理器混合宏(兼容性好,工程化项目常用)
如果项目用了Sass/Less等预处理器,可以把重复的变量定义成混合宏,两处调用即可避免代码重复:
// 定义暗色主题变量混合宏 @mixin dark-theme { --color: #fff; --bg: #000; --hover: #555; } :root { --color: #000; --bg: #fff; --hover: #eee; } @media screen and (prefers-color-scheme: dark) { :root { @include dark-theme; } } body.dark { @include dark-theme; }
方案3:JS配合类控制(兼容性最优,无CSS特性依赖)
不用写媒体查询的CSS规则,用JS监听系统主题偏好,当用户没有手动切换主题时,自动根据系统偏好给body加/删dark类,CSS只需要保留一份body.dark的规则即可:
:root { --color: #000; --bg: #fff; --hover: #eee; } body.dark { --color: #fff; --bg: #000; --hover: #555; }
配套JS参考逻辑:
// 优先读取用户本地存储的手动主题设置 const userTheme = localStorage.getItem('theme') if (userTheme === 'dark') { document.body.classList.add('dark') } else if (!userTheme && window.matchMedia('(prefers-color-scheme: dark)').matches) { // 没有手动设置时跟随系统 document.body.classList.add('dark') }
内容的提问来源于stack exchange,提问作者erosman
相关产品推荐
相关产品推荐

