核心概念
理解并自定义 Tailwind 如何扫描你的源文件。
Tailwind 的工作原理是扫描你的项目中的工具类,然后基于你实际使用的类生成所有必要的 CSS。
这确保了你的 CSS 尽可能小,同时也使得任意值等功能成为可能。
Tailwind 将所有源文件视为纯文本处理,不会尝试以任何方式将文件解析为代码。
相反,它只是基于 Tailwind 预期的类名字符特征,在文件中查找所有可能作为类的标记:
export function Button({ color, children }) { const colors = { black: "bg-black text-white", blue: "bg-blue-500 text-white", white: "bg-white text-black", }; return ( <button className={`${colors[color]} rounded-full px-2 py-1.5 font-sans text-sm/6 font-medium shadow`}> {children} </button> );}
然后它会尝试为所有这些标记生成 CSS,并丢弃那些框架无法识别的非工具类标记。
由于 Tailwind 是以纯文本形式扫描你的源文件,它无法理解你所使用的编程语言中的字符串拼接或插值。
不要动态构建类名
<div class="text-{{ error ? 'red' : 'green' }}-600"></div>
在上面的例子中,字符串 text-red-600
和 text-green-600
并不存在,因此 Tailwind 不会生成这些类。
相反,请确保你使用的任何类名都是完整存在的:
始终使用完整的类名
<div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>
如果你正在使用 React 或 Vue 这样的组件库,这意味着你不应该使用 props 来动态构建类名:
不要使用 props 动态构建类名
function Button({ color, children }) { return <button className={`bg-${color}-600 hover:bg-${color}-500 ...`}>{children}</button>;}
相反,应该将 props 映射到构建时可静态检测的完整类名:
始终将 props 映射到静态类名
function Button({ color, children }) { const colorVariants = { blue: "bg-blue-600 hover:bg-blue-500", red: "bg-red-600 hover:bg-red-500", }; return <button className={`${colorVariants[color]} ...`}>{children}</button>;}
这样做还有一个额外好处,例如你可以将不同的 prop 值映射到不同的颜色深浅:
function Button({ color, children }) { const colorVariants = { blue: "bg-blue-600 hover:bg-blue-500 text-white", red: "bg-red-500 hover:bg-red-400 text-white", yellow: "bg-yellow-300 hover:bg-yellow-400 text-black", }; return <button className={`${colorVariants[color]} ...`}>{children}</button>;}
只要你始终在代码中使用完整的类名,Tailwind 每次都能完美生成所有的 CSS。
Tailwind 会扫描项目中所有文件中的类名,但以下情况除外:
.gitignore
文件中的文件如果需要扫描被 Tailwind 默认忽略的文件,可以显式注册这些源文件。
使用 @source
指令显式注册相对于样式表的源路径:
@import "tailwindcss";@source "../node_modules/@acmecorp/ui-lib";
这在需要扫描使用 Tailwind 构建的外部库时特别有用,因为依赖项通常列在 .gitignore
文件中,默认会被 Tailwind 忽略。
Tailwind 默认使用当前工作目录作为扫描类名的起点。
要显式设置源文件检测的基础路径,可以在 CSS 中导入 Tailwind 时使用 source()
函数:
@import "tailwindcss" source("../src");
这在处理 monorepo 时很有用,因为构建命令通常是从 monorepo 根目录运行,而不是从每个项目的根目录运行。
使用 @source not
指令可以在扫描类名时忽略相对于样式表的特定路径:
@import "tailwindcss";@source not "../src/components/legacy";
当项目中存在已知不使用 Tailwind 类的大型目录(如遗留组件或第三方库)时,这个功能非常实用。
如果你想显式注册所有源文件,可以使用 source(none)
来完全禁用自动源检测:
@import "tailwindcss" source(none);@source "../admin";@source "../shared";
这在拥有多个 Tailwind 样式表的项目中特别有用,可以确保每个样式表只包含其所需的类名。
如果你需要确保 Tailwind 生成某些不存在于内容文件中的类名,可以使用 @source inline()
强制生成它们:
@import "tailwindcss";@source inline("underline");
.underline { text-decoration: underline;}
你也可以使用 @source inline()
来生成带有变体的类。例如,要生成带有 hover 和 focus 变体的 underline
类,可以在源输入中添加 {hover:,focus:,}
:
@import "tailwindcss";@source inline("{hover:,focus:,}underline");
.underline { text-decoration: underline;}@media (hover: hover) { .hover\:underline:hover { text-decoration: underline; }}@media (focus: focus) { .focus\:underline:focus { text-decoration: underline; }}
源输入采用大括号扩展语法,因此您可以一次性生成多个类。例如,要生成所有红色背景色及其悬停变体,可以使用范围:
@import "tailwindcss";@source inline("{hover:,}bg-red-{50,{100..900..100},950}");
.bg-red-50 { background-color: var(--color-red-50);}.bg-red-100 { background-color: var(--color-red-100);}.bg-red-200 { background-color: var(--color-red-200);}/* ... */.bg-red-800 { background-color: var(--color-red-800);}.bg-red-900 { background-color: var(--color-red-900);}.bg-red-950 { background-color: var(--color-red-950);}@media (hover: hover) { .hover\:bg-red-50:hover { background-color: var(--color-red-50); } /* ... */ .hover\:bg-red-950:hover { background-color: var(--color-red-950); }}
这会生成从100到900(步长为100)的红色背景色,以及首尾的50和950色阶。同时还会为每个类添加hover:
变体。
使用@source not inline()
可以阻止特定类的生成,即使它们在源文件中被检测到:
@import "tailwindcss";@source not inline("{hover:,focus:,}bg-red-{50,{100..900..100},950}");
这将显式排除红色背景工具类及其悬停和焦点变体的生成。