在Vite中让TailwindCSS与Ant Design同步暗黑模式

前段时间探索了 Next.js,很是惊讶于它对各种前沿特性(如 RSC)的支持。但囿于 RSC 和 Next.js 在最近可谓是漏洞不断(比如大名鼎鼎的 CVE-2025-55182),加上仔细思考之后意识到很多情景并不需要 SSR 或者 RSC,我决定返回 CSR 的领域。

在各种项目搭建工具都很成熟的当今,已经没必要从零开始手搓 webpack 配置了——我选择的工具是 Vite。Vite 会帮助你配置大部分的组件,如打包器、TypeScript、React、ESLint。一些额外的组件,比如 React Routeri18nextStylelintPrettier,也很容易添加。唯一有点麻烦的,是让 TailwindCSS 和 Ant Design 共存,并且共享暗黑模式的状态。这里记录一下我的配置思路和过程。

TailwindCSS

在 Vite 中使用 TailwindCSS 首先需要安装以下包:

1
pnpm add -D tailwindcss @tailwindcss/vite

接着,修改 vite.config.js

1
2
3
4
5
6
7
8
  import { defineConfig } from 'vite'
+ import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
plugins: [
+ tailwindcss(),
],
})

最后,修改顶层 CSS 文件:

1
@import "tailwindcss";

这样就可以开始使用 TailwindCSS 了。

Ant Design

在 Vite 中使用 Ant Design 只需要安装以下包:

1
pnpm add antd @ant-design/cssinjs

需要注意的是,Ant Design 默认不使用 CSS 的 @layer,而 TailwindCSS 使用,因此 Ant Design 的样式会直接覆盖 TailwindCSS 的样式。为了解决这个问题,需要让 Ant Design 也使用 CSS 的 @layer 并手动配置不同分层的优先级。

在顶层组件中,用 <StyleProvider> (来自 @ant-design/cssinjs)包裹应用组件:

1
2
3
4
5
6
7
8
9
10
11
12
+ import { StyleProvider } from '@ant-design/cssinjs';
+ import { ConfigProvider } from 'antd';

export default () => {
return (
+ <StyleProvider layer>
+ <ConfigProvider>
<App />
+ </ConfigProvider>
+ </StyleProvider>
);
};

同时,在顶层 CSS 中,配置不同分层的优先级:

1
2
3
+ @layer theme, base, antd, components, utilities;
+
@import 'tailwindcss';

暗黑模式

TailwindCSS 的 dark: 变体默认由 prefers-color-scheme 媒体查询决定是否激活,而媒体查询并不受 JavaScript 控制。Ant Design 的暗黑主题则需要通过 React 状态控制。为了能统一控制它们的暗黑模式的开关,需要做以下几件事。

首先,在顶层 CSS 中,让 TailwindCSS 根据 <html> 标签上是否存在 class="dark" 来决定是否激活 dark: 变体:

1
2
3
4
5
  @layer theme, base, antd, components, utilities;

@import "tailwindcss";
+
+ @custom-variant dark (&:where(.dark, .dark *));

接着,安装 usehooks-ts,它提供了 useDarkMode() 等钩子来管理暗黑模式状态:

1
pnpm add usehooks-ts

最后,在顶层组件中,用 useDarkMode() 获取暗黑模式状态,通过 useEffect 将其同步到 <html> 标签的 class="dark" 上,再将其传给 Ant Design 的 <ConfigProvider>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
+ import { useEffect } from 'react';
+ import { useDarkMode } from 'usehooks-ts';
import { StyleProvider } from '@ant-design/cssinjs';
- import { ConfigProvider } from 'antd';
+ import { ConfigProvider, theme } from 'antd';

export default () => {
+ const { isDarkMode } = useDarkMode();
+
+ useEffect(() => {
+ document.documentElement.classList.toggle('dark', isDarkMode);
+ }, [isDarkMode]);
+
return (
<StyleProvider layer>
- <ConfigProvider>
+ <ConfigProvider theme={{ algorithm: isDarkMode ? theme.darkAlgorithm : theme.defaultAlgorithm }}>
<App />
</ConfigProvider>
</StyleProvider>
);
};

这样,useDarkMode() 的状态就同时控制了 TailwindCSS 和 Ant Design 的暗黑模式的开关。如图:

1
2
3
4
5
6
7
8
        useDarkMode()

┌───────┴───────┐
▼ ▼
<html class="dark"> <ConfigProvider>
│ │
▼ ▼
TailwindCSS Ant Design

参考资料


在Vite中让TailwindCSS与Ant Design同步暗黑模式
https://tomzhu.site/2026/06/17/在Vite中让TailwindCSS与Ant-Design同步暗黑模式/
作者
Tom Zhu
发布于
2026年6月17日
许可协议