Tailwind CSS v4 移除 tailwindcss.config.js 后如何配置进行主题切换

boyanx1周前技术教程4

在 Tailwind CSS v4 中,tailwindcss.config.js 配置文件已被移除,取而代之的是 postcss.config.js。由于此次更新涉及较大变动,本文将记录如何在 Next.js 项目中结合 Tailwind CSS v4 实现可切换的自定义主题。

配置文件变更

Content 配置

变更前(Tailwind CSS v3 及之前): 需要在 tailwindcss.config.js 中手动指定扫描的文件路径,例如:

module.exports = {
  content: ['./src/**/*.{html,js}'],
}


变更后(Tailwind CSS v4): Tailwind CSS 现在会自动扫描相关文件,因此无需再手动配置 content 选项。


Plugin 配置

变更前: 插件需要在 tailwindcss.config.js 中手动引入,例如:

module.exports = {
  plugins: [
    require('daisyui'),
  ],
}


变更后: 可以直接在 CSS 文件中使用 @plugin 语法引入插件:

@plugin "daisyui";


Prefix 配置

变更前: 如果需要为 Tailwind CSS 的所有实用类添加前缀(如 tw-),需要在配置文件中定义:

module.exports = {
  prefix: 'tw-'
}


变更后: 可以在 CSS 文件中引入 Tailwind CSS 时直接指定前缀,例如:

@import "tailwindcss" prefix(tw);


e.g. 在项目中使用 Tailwind CSS 类名时,需按如下方式调用:

const App = () => {
  return (
    <div className="tw:text-gray-500">app</div>
  )
}


Theme 主题配置

变更前: 自定义主题颜色需要在 tailwindcss.config.js 中定义:

module.exports = {
  theme: {
    screens: {
      sm: '480px'
    },
    extend: {
      colors: {
        "twitter-blue": "#1DA1F2"
      }
    },
  },
}


变更后: 可直接在 CSS 文件中使用 @theme 语法定义主题变量:

@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 属性指定主题

@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 存储,确保主题状态能在页面刷新后保持。

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,确保主题状态在应用启动时正确应用。

"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 组件用于测试是否可以在亮色模式和深色模式之间切换

"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,确保主题切换在整个应用中生效

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)

标签: css初始化

相关文章

HTML中script标签中的那些属性(html script属性)

HTML中的<script>标签详解 在HTML中,<script> 标签用于包含或引用JavaScript代码,是前端开发中不可或缺的一部分。通过合理使用 <scrip...

HtmlToPDFCore:HTML 转换为 PDF 的利器,轻便,快捷,重量级

在日常开发中,我们常常需要将动态生成的 HTML 内容转换为 PDF 文件。无论是用于打印、存档还是分享,PDF 格式都因其跨平台兼容性和稳定性而备受青睐。今天,我们就来介绍一个强大的工具——Htm...

CSS的4种引入方式及优先级(css的4种引入方式及优先级是什么)

CSS的4种引入方式是:行内样式、内嵌样式、链接样式、导入样式1.行内样式最直接最简单的一种,直接对HTML标签使用style="",例如:<p style="color:#F00; ">...

5年前学习null和undefined,现在有新的认知,看看这位人才怎么说

许多编程语言都有一个称为null的非值。它指示一个变量当前不指向一个对象,例如,当它还没有初始化的时候。相比之下,JavaScript有两个这样的非值:undefined和null。在这篇博文中,我们...

初始化docker运行环境(docker start docker run)

docker的国内镜像可用性经常让人走很多弯路。这里将限定特定的环境,将基本操作步骤和遇到的问题逐一呈现,减少后来者曲折。环境可以上网的工作电脑,操作系统为ubuntu 24.04版本,网卡接入本地局...

没了恢复选项怎么办?Windows Defender也能初始化电脑

在经过了Windows 7、Vista和Windows 8/8.1的不断进化,作为排障手段之一的系统恢复功能可以说能将就用用了。恢复后的Windows 10虽然没有格盘重装来的干净,但多少会解决一些软...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。