跳到正文
笔记库
样式2 分钟成长中

Tailwind v4 接入:从「指令」到「导入」的一行之差

v3 的 @tailwind 指令在 v4 里已经不存在了。写错不会报错,只会让你的样式静默消失。

Tailwind v4 最大的变化不是新特性,而是接入方式换了。旧的三行指令在新版本里没有任何意义,但它们依然能被 CSS 解析器接受——所以写错了不会报错,只会静默失效。

两代接入方式的区别

/* v3:三条指令,靠 PostCSS 扫描内容后注入 */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* v4:一条 import,靠 Vite 插件在构建期完成 */
@import 'tailwindcss';

v4 把 PostCSS 换成了一个真正的打包器插件,所以还多了一步配置:

// vite.config.ts
import tailwindcss from '@tailwindcss/vite'
 
export default defineConfig({
  plugins: [react(), tailwindcss()],
})

少了这个插件,@import 'tailwindcss' 会由 Vite 的 CSS 处理去解析——它能找到 node_modules 里的文件,于是不报错,但也不会按你的内容生成工具类。

怎么确认它真的在工作

不要看页面,看产物里的字节数。

$ npx vite build
dist/assets/index-*.css   49.32 kB   # 生效
dist/assets/index-*.css   11.04 kB   # 没生效(只剩预置样式)

再抓几个实际用到的类名:

$ for c in min-h-screen backdrop-blur text-8xl bg-surface; do
>   printf "%s: " "$c"; grep -c "$c" dist/assets/*.css
> done
min-h-screen: 1
backdrop-blur: 3
text-8xl: 1
bg-surface: 1

设计令牌用 @theme inline

v4 的 @theme 会把变量变成工具类,但它默认是静态的:切换主题时变量不会跟着变。

要让主题切换生效,需要两步:语义变量定义在 :root 上,@theme 里用 inline 引用它们。

:root {
  --bg: #0b0f19;
  --fg: #e6e8ee;
}
 
[data-theme='light'] {
  --bg: #fcfcfd;
  --fg: #16181d;
}
 
@theme inline {
  --color-bg: var(--bg);
  --color-fg: var(--fg);
}

inline 的含义是"把这个值原样写进工具类",而不是"复制一份常量"。于是 bg-bg 编译成 background-color: var(--bg),data-theme 一变,所有用到它的地方同时变——一行 JS 都不用写。

完整的切换链路——首帧内联脚本、useSyncExternalStore、两套变量的维护纪律——单独记在 主题切换不该经过 React。

顺带的两个坑

  1. baseUrl 在 TS 6 里已废弃,写了会直接报 TS5101。路径别名只写 paths 即可,Vite 侧用 resolve.alias 对齐。
  2. framer-motion 和 motion 不要同时装。motion/react 本身已经依赖前者,多装一个只是让 lockfile 更重。

现在这套配置的约束

  • 字阶、间距、圆角、动效时长全部在 @theme 里,组件里不许出现魔法数字;
  • 颜色只用语义名(bg / surface / line / fg / muted),不许出现 indigo-500 这类色板名;
  • 深浅两套主题共用同一批变量,新增颜色必须两套都补。

接着读

留言

还没有人说话

读到这里,说两句。不用登录,昵称随便填。

不用登录
0 / 1200

文字原样显示,不支持 Markdown。发完可以删。