tailwind.config.js 文件的 content 部分是配置所有 HTML 模板、JavaScript 组件和任何其他包含 Tailwind 类名的源文件的路径。

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
  ],
  // ...
}

本指南涵盖了你需要了解的所有内容,以确保 Tailwind 为你的项目生成所有必需的 CSS。


配置源路径

Tailwind CSS 通过扫描所有 HTML、JavaScript 组件和任何其他模板文件以查找类名,然后为这些样式生成所有对应的 CSS 来工作。

为了让 Tailwind 生成所有你需要的 CSS,它需要了解项目中包含任何 Tailwind 类名的每个文件。

在配置文件的 content 部分配置所有内容文件的路径

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}'
  ],
  // ...
}

路径配置为 glob 模式,这使得在不进行大量配置的情况下轻松匹配项目中的所有内容文件

  • 使用 * 匹配除斜杠和隐藏文件之外的任何内容
  • 使用 ** 匹配零个或多个目录
  • {} 之间使用逗号分隔值以匹配一组选项

Tailwind 在底层使用 fast-glob 库 — 查看其文档以了解其他支持的模式功能。

路径相对于项目根目录,而不是 tailwind.config.js 文件,因此,如果 tailwind.config.js 文件位于自定义位置,你仍应相对于项目根目录编写路径。

模式建议

为了获得最佳性能并避免误报,请尽可能具体地配置内容。

如果你使用像这样的非常宽泛的模式,Tailwind 甚至会扫描 node_modules 以查找内容,这可能不是你想要的

不要使用极其宽泛的模式

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './**/*.{html,js}',
  ],
  // ...
}

如果你有任何需要扫描的文件位于项目根目录(通常是 index.html 文件),请独立列出该文件,以便其他模式可以更具体

具体说明你的内容模式

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './components/**/*.{html,js}',
    './pages/**/*.{html,js}',
    './index.html',
  ],
  // ...
}

一些框架将它们的主 HTML 入口点隐藏在与其他模板不同的地方(通常是 public/index.html),因此,如果你将 Tailwind 类添加到该文件中,请确保它也包含在配置中

如果适用,请记住包含你的 HTML 入口点

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

如果你有任何操纵 HTML 以添加类的 JavaScript 文件,请确保也将其包含在内

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    // ...
    './src/**/*.js',
  ],
  // ...
}
src/spaghetti.js
// ...
menuButton.addEventListener('click', function () {
  let classList = document.getElementById('nav').classList
  classList.toggle('hidden')
  classList.toggle('block')
})
// ...

同样重要的是,不要扫描任何 CSS 文件——将 Tailwind 配置为扫描你的类名正在使用的模板,而不是 Tailwind 生成的 CSS 文件。

切勿在内容配置中包含 CSS 文件

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './src/**/*.css',
  ],
  // ...
}

深入了解类检测

Tailwind 扫描源代码以查找类的做法非常简单——我们实际上不会解析或执行任何以其编写的语言编写的代码,我们只是使用正则表达式来提取可能成为类名的每个字符串。

例如,这里有一些 HTML,每个潜在的类名字符串都单独突出显示

<div class="md:flex">
  <div class="md:flex-shrink-0">
    <img class="rounded-lg md:w-56" src="/img/shopping.jpg" alt="Woman paying for a purchase">
  </div>
  <div class="mt-4 md:mt-0 md:ml-6">
    <div class="uppercase tracking-wide text-sm text-indigo-600 font-bold">
      Marketing
    </div>
    <a href="/get-started" class="block mt-1 text-lg leading-tight font-semibold text-gray-900 hover:underline">
      Finding customers for your new business
    </a>
    <p class="mt-2 text-gray-600">
      Getting a new business off the ground is a lot of hard work.
      Here are five ideas you can use to find your first customers.
    </p>
  </div>
</div>

我们不会将搜索仅限制在 class="..." 属性,因为你可以在任何地方使用类,比如在一些用于切换菜单的 JavaScript 中

spaghetti.js
<script>
  menuButton.addEventListener('click', function () {
    let classList = document.getElementById('nav').classList
    classList.toggle('hidden')
    classList.toggle('block')
  })
</script>

通过使用这种非常简单的方法,Tailwind 可以与任何编程语言非常可靠地一起使用,例如 JSX

Button.jsx
const sizes = {
  md: 'px-4 py-2 rounded-md text-base',
  lg: 'px-5 py-3 rounded-lg text-lg',
}

const colors = {
  indigo: 'bg-indigo-500 hover:bg-indigo-600 text-white',
  cyan: 'bg-cyan-600 hover:bg-cyan-700 text-white',
}

export default function Button({ color, size, children }) {
  let colorClasses = colors[color]
  let sizeClasses = sizes[size]

  return (
    <button type="button" className={`font-bold ${sizeClasses} ${colorClasses}`}>
      {children}
    </button>
  )
}

动态类名

Tailwind 提取类名的最重要含义在于,它只会在源文件中找到作为完整不间断字符串存在的类。

如果你使用字符串插值或将部分类名连接在一起,Tailwind 将找不到它们,因此不会生成相应的 CSS

不要动态构建类名

<div class="text-{{ error ? 'red' : 'green' }}-600"></div>

在上面的示例中,字符串text-red-600text-green-600不存在,因此 Tailwind 不会生成这些类。

相反,确保你使用的任何类名都完整存在

始终使用完整的类名

<div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>

如果你正在使用 React 或 Vue 等组件库,这意味着你不应该使用道具动态构建类

不要使用道具动态构建类名

function Button({ color, children }) {
  return (
    <button className={`bg-${color}-600 hover:bg-${color}-500 ...`}>
      {children}
    </button>
  )
}

相反,将道具映射到在构建时可以静态检测到的完整类名

始终将道具映射到静态类名

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>
  )
}

这具有额外的优点,例如允许你将不同的道具值映射到不同的颜色阴影

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。

与第三方库协作

如果您正在使用任何第三方库(例如 Select2),并使用您自己的自定义 CSS 为该库设置样式,我们建议在使用 Tailwind 的 @layer 功能的情况下编写这些样式

main.css
@tailwind base;
@tailwind components;

.select2-dropdown {
  @apply rounded-b-lg shadow-md;
}
.select2-search {
  @apply border border-gray-300 rounded;
}
.select2-results__group {
  @apply text-lg font-bold text-gray-900;
}
/* ... */

@tailwind utilities;

这将确保 Tailwind 始终在您的 CSS 中包含这些样式,这比配置 Tailwind 扫描第三方库的源代码容易得多。

如果您创建了自己的可重复使用的组件集,这些组件使用 Tailwind 设置了样式,并且在多个项目中导入它们,请确保将 Tailwind 配置为扫描这些组件以查找类名

tailwind.config.js
module.exports = {
  content: [
    './components/**/*.{html,js}',
    './pages/**/*.{html,js}',
    './node_modules/@my-company/tailwind-components/**/*.js',
  ],
  // ...
}

这将确保 Tailwind 也为这些组件生成所有必需的 CSS。

如果您正在使用具有工作空间的单一仓库,您可能需要使用 require.resolve 来确保 Tailwind 可以看到您的内容文件

tailwind.config.js
const path = require('path');

module.exports = {
  content: [
    './components/**/*.{html,js}',
    './pages/**/*.{html,js}',
    path.join(path.dirname(require.resolve('@my-company/tailwind-components')), '**/*.js'),
  ],
  // ...
}

使用相对路径

默认情况下,Tailwind 解析相对于当前工作目录的非绝对内容路径,而不是 tailwind.config.js 文件。如果您从其他目录运行 Tailwind,这可能会导致意外结果。

要始终解析相对于 tailwind.config.js 文件的路径,请对您的 content 配置使用对象表示法,并将 relative 属性设置为 true

tailwind.config.js
module.exports = {
  content: {
    relative: true,
    files: [
      './pages/**/*.{html,js}',
      './components/**/*.{html,js}',
    ],
  },
  // ...
}

这可能会成为框架下一个主要版本的默认行为。

配置原始内容

如果您出于某种原因需要配置 Tailwind 扫描某些原始内容而不是文件的内容,请使用带有 raw 键的对象,而不是路径

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
    { raw: '<div class="font-bold">', extension: 'html' },
  ],
  // ...
}

这没有很多有效的用例——安全列出通常是您真正想要的。


安全列出类

为了获得最小的文件大小和最佳的开发体验,我们强烈建议依靠你的 content 配置来尽可能多地告诉 Tailwind 要生成哪些类。

安全列出是最后的手段,只应在无法扫描某些内容以查找类名的情况下使用。这些情况很少见,你几乎永远不需要此功能。

如果你需要确保 Tailwind 生成某些不存在于你的内容文件中的类名,请使用 safelist 选项

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
  ],
  safelist: [
    'bg-red-500',
    'text-3xl',
    'lg:text-4xl',
  ]
  // ...
}

一个有用的示例是,如果你的网站显示用户生成的内容,并且你希望用户能够在他们的内容中使用一组受限的 Tailwind 类,而这些类可能不存在于你自己的网站源文件中。

使用正则表达式

Tailwind 支持基于模式的安全列出,以应对需要安全列出大量类的这种情况

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
  ],
  safelist: [
    'text-2xl',
    'text-3xl',
    {
      pattern: /bg-(red|green|blue)-(100|200|300)/,
    },
  ],
  // ...
}

模式只能匹配基本实用程序名称,例如 /bg-red-.+/,并且如果模式包含变体修饰符(例如 /hover:bg-red-.+/),则不会匹配。

如果你想强制 Tailwind 为任何匹配的类生成变体,请使用 variants 选项将其包含在内

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
  ],
  safelist: [
    'text-2xl',
    'text-3xl',
    {
      pattern: /bg-(red|green|blue)-(100|200|300)/,
      variants: ['lg', 'hover', 'focus', 'lg:hover'],
    },
  ],
  // ...
}

丢弃类

由于 Tailwind 使用非常简单的方法来检测内容中的类名,因此你可能会发现生成了一些你实际上不需要的类。

例如,此 HTML 仍会生成 container 类,即使该类实际上并未被使用

<div class="text-lg leading-8 text-gray-600">
  Every custom pool we design starts as a used shipping container, and is
  retrofitted with state of the art technology and finishes to turn it into
  a beautiful and functional way to entertain your guests all summer long.
</div>

您可能还想防止 Tailwind 在这些类与某些现有 CSS 冲突时生成某些类,但您不想对所有 Tailwind 类进行前缀。

在这些情况下,您可以使用 blocklist 选项告诉 Tailwind 忽略它在您的内容中检测到的特定类

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
  ],
  blocklist: [
    'container',
    'collapse',
  ],
  // ...
}

blocklist 选项仅影响 Tailwind 生成的 CSS,而不影响您自己编写的或从其他库导入的自定义 CSS。

safelist 不同,blocklist 选项仅支持字符串,您不能使用正则表达式来阻止类。


转换源文件

如果您正在以编译为 HTML 的格式(例如 Markdown)编写内容,那么在扫描类名之前将其编译为 HTML 通常是有意义的。

使用 content.transform 选项在提取类之前转换与特定文件扩展名匹配的任何内容

tailwind.config.js
const remark = require('remark')

module.exports = {
  content: {
    files: ['./src/**/*.{html,md}'],
    transform: {
      md: (content) => {
        return remark().process(content)
      }
    }
  },
  // ...
}

在使用 content.transform 时,您需要使用 content.files 而不是作为 content 下的顶级数组来提供您的源路径。


自定义提取逻辑

使用 extract 选项覆盖 Tailwind 用于检测特定文件扩展名的类名的逻辑

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: {
    files: ['./src/**/*.{html,wtf}'],
    extract: {
      wtf: (content) => {
        return content.match(/[^<>"'`\s]*/g)
      }
    }
  },
  // ...
}

这是一个高级功能,大多数用户不需要它——Tailwind 中的默认提取逻辑几乎适用于所有项目。

与转换类似,在使用 content.extract 时,您需要使用 content.files 而不是 content 下的顶级数组来提供源路径。


故障排除

未生成类

如果 Tailwind 未生成类,请确保您的 content 配置正确且匹配所有正确的源文件。

一个常见的错误是缺少文件扩展名,例如,如果您在 React 组件中使用 jsx 而不是 js

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

或者在项目中期创建了一个最初未涵盖的新文件夹,并忘记将其添加到您的配置中

tailwind.config.js
module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
    './util/**/*.{html,js}'
  ],
  // ...
}

也可能是您尝试使用动态类名,这将不起作用,因为 Tailwind 实际上不会评估您的源代码,只能检测到静态的未中断的类字符串。

不要动态构建类名

<div class="text-{{ error ? 'red' : 'green' }}-600"></div>

确保始终在代码中使用完整的类名

始终使用完整的类名

<div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>

阅读我们关于 动态类名 的文档以了解更多详细信息。

样式在无限循环中重建

如果您的 CSS 似乎在无限循环中重建,很可能是因为您的构建工具在 注册 PostCSS 依赖项 时不支持 glob 选项。

许多构建工具(例如 webpack)不支持此选项,因此我们只能告诉它们监视特定文件或整个目录。例如,我们无法告诉 webpack 监视目录中的 *.html 文件。

这意味着,如果构建 CSS 导致这些目录中的任何文件发生更改,即使更改的文件与 glob 中的扩展名不匹配,也会触发重建。

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    // With some build tools, your CSS will rebuild
    // any time *any* file in `src` changes.
    './src/**/*.{html,js}',
  ],
  // ...
}

因此,如果您正在监视 src/**/*.html 的更改,但将 CSS 输出文件写入 src/css/styles.css,则使用某些工具会得到一个无限的重建循环。

理想情况下,我们可以在控制台中对此发出警告,但许多工具对此支持得很好(包括我们自己的 CLI 工具),我们没有可靠的方法来检测您正在使用什么构建工具。

要解决此问题,请在你的 content 配置中使用更具体的路径,确保只包含在你的 CSS 构建时不会更改的目录

tailwind.config.js
module.exports = {
  content: [
    './src/**/*.{html,js}',
    './src/pages/**/*.{html,js}',
    './src/components/**/*.{html,js}',
    './src/layouts/**/*.{html,js}',
    './src/index.html',
  ],
  // ...
}

如果需要,调整你的实际项目目录结构以确保你可以针对你的模板文件,而不会意外地捕获你的 CSS 文件或其他构建工件(如清单文件)。

如果你绝对无法更改你的内容配置或目录结构,你的最佳选择是使用完全支持 glob 的工具单独编译你的 CSS。我们建议使用 Tailwind CLI,它是一个快速、简单、专门用于使用 Tailwind 编译 CSS 的工具。

它根本无法正常工作

如果你遇到了奇怪的、难以描述的输出问题,或者事情看起来根本不起作用,很有可能是因为你的构建工具不支持 PostCSS 依赖项消息(或者根本不支持)。目前已知的一个例子是 Stencil

当你遇到此类问题时,我们建议使用 Tailwind CLI 单独编译你的 CSS,而不是尝试将 Tailwind 集成到你的现有工具中。

你可以使用 npm-run-allconcurrently 等包通过向你的项目添加一些脚本来编译你的 CSS 和你的常规开发命令,如下所示

// package.json
{
  // ...
  "scripts": {
    "start": "concurrently \"npm run start:css\" \"react-scripts start\"",
    "start:css": "tailwindcss -o src/tailwind.css --watch",
    "build": "npm run build:css && react-scripts build",
    "build:css": "NODE_ENV=production tailwindcss -o src/tailwind.css -m",
  },
}

无论哪种方式,请务必 检查现有问题打开一个新问题,以便我们可以找出问题并尝试提高与你正在使用的任何工具的兼容性。