在 Tailwind CSS v4 中,tailwindcss.config.js
配置文件已被移除,取而代之的是 postcss.config.js
。由于此次更新涉及较大变动,本文将记录如何在 Next.js 项目中结合 Tailwind CSS v4 实现可切换的自定义主题。
配置文件变更
Content 配置
变更前 (Tailwind CSS v3 及之前): 需要在 tailwindcss.config.js
中手动指定扫描的文件路径,例如:
ts
module.exports = {
content: ['./src/**/*.{html,js}'],
}
变更后 (Tailwind CSS v4): Tailwind CSS 现在会自动扫描相关文件,因此无需再手动配置 content
选项。
Plugin 配置
变更前 : 插件需要在 tailwindcss.config.js
中手动引入,例如:
ts
module.exports = {
plugins: [
require('daisyui'),
],
}
变更后 : 可以直接在 CSS 文件中使用 @plugin
语法引入插件:
css
@plugin "daisyui";
Prefix 配置
变更前 : 如果需要为 Tailwind CSS 的所有实用类添加前缀(如 tw-
),需要在配置文件中定义:
ts
module.exports = {
prefix: 'tw-'
}
变更后: 可以在 CSS 文件中引入 Tailwind CSS 时直接指定前缀,例如:
css
@import "tailwindcss" prefix(tw);
e.g. 在项目中使用 Tailwind CSS 类名时,需按如下方式调用:
tsx
const App = () => {
return (
<div className="tw:text-gray-500">app</div>
)
}
Theme 主题配置
变更前 : 自定义主题颜色需要在 tailwindcss.config.js
中定义:
ts
module.exports = {
theme: {
screens: {
sm: '480px'
},
extend: {
colors: {
"twitter-blue": "#1DA1F2"
}
},
},
}
变更后 : 可直接在 CSS 文件中使用 @theme
语法定义主题变量:
css
@theme {
--breakpoint-*: initial;
--breakpoint-sm: 480px;
--color-twitter-blue: #1DA1F2;
--color-orange-500: #ffa500;
}
更多关于 Tailwind CSS 主题变量命名的信息,请参考官方文档:Theme Variable Namespaces。
主题切换
根据官方文档的 referencing-other-variables,Tailwind CSS 4 引入了 @theme inline
关键字,可以对 CSS 变量进行引用。
以下是一个结合 zustand 对 theme 主题色进行状态管理并持久化的例子:
配置全局主题变量
在 global.css
中,我们使用 @theme inline
定义主题变量,并通过 data-theme
属性指定主题
css
@import "tailwindcss";
@theme inline {
--color-primary: var(--color-brand);
--color-background: var(--color-bg);
--color-text: var(--color-tx);
}
/* 亮色模式 */
[data-theme="light"] {
--color-brand: #1DA1F2;
--color-bg: #ffffff;
--color-tx: #333333;
}
/* 深色模式 */
[data-theme="dark"] {
--color-brand: #ff9800;
--color-bg: #1a1a1a;
--color-tx: #f5f5f5;
}
使用 zustand 进行状态管理
在 store/themeStore.ts
中创建 Zustand 存储,确保主题状态能在页面刷新后保持。
tsx
import { create } from "zustand";
import { persist } from "zustand/middleware";
export const useThemeStore = create(
persist(
(set) => ({
theme: "light",
setTheme: (newTheme: "light" | "dark") => set({ theme: newTheme }),
}),
{
name: "theme-storage",
}
)
);
创建 ThemeProvider
组件
在 ThemeProvider.tsx
中初始化当前 theme,确保主题状态在应用启动时正确应用。
tsx
"use client";
import { useEffect } from "react";
import { useThemeStore } from "@/store/themeStore";
export default function ThemeProvider({ children }: { children: React.ReactNode }) {
const { theme } = useThemeStore();
useEffect(() => {
document.documentElement.setAttribute("data-theme", theme);
}, [theme]);
return <>{children}</>;
}
主题切换按钮
ThemeToggle.tsx
组件用于测试是否可以在亮色模式和深色模式之间切换
tsx
"use client";
import { useThemeStore } from "@/store/themeStore";
import { useEffect } from "react";
export default function ThemeToggle() {
const { theme, setTheme } = useThemeStore();
useEffect(() => {
document.documentElement.setAttribute("data-theme", theme);
}, [theme]);
return (
<button
className="px-4 py-2 rounded-lg transition-all"
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
>
{theme === "light" ? "🌙 深色模式" : "☀️ 亮色模式"}
</button>
);
}
在 layout.tsx
中引入主题
在 app/layout.tsx
文件中引入 ThemeProvider
和 ThemeToggle
,确保主题切换在整个应用中生效
tsx
import ThemeProvider from "@/components/ThemeProvider";
import ThemeToggle from "@/components/ThemeToggle";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="zh-CN">
<body>
<ThemeProvider>
{children}
<ThemeToggle />
<div className="text-primary">test</div>
</ThemeProvider>
</body>
</html>
);
}
现在点击切换按钮,可以发现文字 test 已经可以随着按钮点击而变化颜色了。
v4 配置介绍相关内容来自:The NEW CSS-first configuration with Tailwind CSS v4 (No more tailwind.config.js)