最近我在使用 UnoCSS 构建一个项目时,遇到了一些让人很头大的问题。尤其是在处理暗色模式(dark mode)时,一些样式总是无法生效,最终通过不断调试和查阅资料,才终于搞明白问题所在。
这篇文章总结一下我踩过的坑,希望能帮到遇到类似情况的你 👇
💡 背景介绍
我使用的是 UnoCSS 的 presetWind4
,配置中选择了暗色模式跟随系统(即 dark: 'media'
):
// uno.config.ts
import { defineConfig, presetWind4 } from 'unocss'
export default defineConfig({
presets: [
presetWind4({
dark: 'media',
}),
],
})
组件中使用的代码类似:
<template>
<header class="bg-yellow-200 dark:bg-yellow-800 text-black dark:text-white">
text
</header>
</template>
🧩 遇到的问题
我最开始以为是暗色模式不生效了,但其实情况更复杂:
- 我发现了暗色模式的样式被普通样式覆盖掉了;
- 最终,通过 DevTools 查看,发现
.bg-yellow-200
的样式在.dark .bg-yellow-800
后面,覆盖了暗色背景; - 而
.dark .bg-yellow-800
是通过媒体查询写成的,因此按优先级反而输给了后面的样式。
🕵️ 问题分析
UnoCSS 是一个原子化 CSS 工具,它会根据你写的 class 生成最小化的样式,但它不会智能处理优先级。
在我的情况中:
<header class="bg-yellow-200 dark:bg-yellow-800" />
生成的 CSS 类似于:
@media (prefers-color-scheme: dark) {
.bg-yellow-800 { background-color: #... } /* 在前 */
}
.bg-yellow-200 { background-color: #... } /* 在后,覆盖了 dark 的 */
这就导致即使浏览器处于暗色模式,也因为 .bg-yellow-200
在后面,被覆盖了。
✅ 解决方案
UnoCSS 提供了 !
用于强制提升某个类的优先级:
<header class="bg-yellow-200 dark:bg-yellow-800!" />
这个方法简单有效,推荐!
🧠 总结
UnoCSS 是个非常强大而灵活的工具,但也因为它“自动”得太彻底,反而会让你忽略一些关键细节。在这次经历中我学到了:
- 🔍 样式冲突有时不是 dark 模式失效,而是优先级和顺序的问题;
- 🧩 Dev 模式和 Build 模式行为不同,要用构建模式仔细验证;
- ⚠ 不要依赖类的书写顺序解决问题,
!
才是根本手段; - 🧹 最好配置好
safelist
,确保构建时不会漏掉样式。
希望这篇文章能帮你少走一点弯路 🙏
如果你也踩过 UnoCSS 的坑,欢迎评论交流!👋
我们都在“被自动化伤害,又被它拯救”的循环中修炼着呢😅
本文初版内容由 ChatGPT 写成。ChatGPT 真的很会写,直接用它写的内容来改,省力多了。