1. 新手入门
  2. 使用预处理器

由于 Tailwind 是一个 PostCSS 插件,没有什么能阻止你将它与 Sass、Less、Stylus 或其他预处理器一起使用,就像你可以与 Autoprefixer 等其他 PostCSS 插件一样。

¥Since Tailwind is a PostCSS plugin, there’s nothing stopping you from using it with Sass, Less, Stylus, or other preprocessors, just like you can with other PostCSS plugins like Autoprefixer.

需要注意的是,你不需要在 Tailwind 中使用预处理器 — 无论如何,你通常在 Tailwind 项目上编写很少的 CSS,因此使用预处理器并不像在编写 很多自定义 CSS。

¥It’s important to note that you don’t need to use a preprocessor with Tailwind — you typically write very little CSS on a Tailwind project anyway, so using a preprocessor just isn’t as beneficial as it would be in a project where you write a lot of custom CSS.

本指南仅作为出于无法控制的原因需要将 Tailwind 与预处理器集成的人员的参考,而不是因为它是推荐的做法。

¥This guide only exists as a reference for people who need to integrate Tailwind with a preprocessor for reasons outside of their control, not because it is a recommended practice.


使用 PostCSS 作为预处理器

¥Using PostCSS as your preprocessor

如果你将 Tailwind 用于一个全新的项目并且不需要将其与任何现有的 Sass/Less/Stylus 样式表集成,你应该高度考虑依赖其他 PostCSS 插件来添加你使用的预处理器功能,而不是使用单独的 预处理器。

¥If you’re using Tailwind for a brand new project and don’t need to integrate it with any existing Sass/Less/Stylus stylesheets, you should highly consider relying on other PostCSS plugins to add the preprocessor features you use instead of using a separate preprocessor.

这有几个好处:

¥This has a few benefits:

  • 你的构建会更快。由于你的 CSS 不必通过多种工具进行解析和处理,因此仅使用 PostCSS 即可更快地编译你的 CSS。

    ¥Your builds will be faster. Since your CSS doesn’t have to be parsed and processed by multiple tools, your CSS will compile much quicker using only PostCSS.

  • 没有怪癖或解决方法。由于 Tailwind 向 CSS 添加了一些新的非标准关键字(如 @tailwind@applytheme() 等),你通常不得不以烦人的、不直观的方式编写 CSS 以获得预处理器来为你提供预期的输出。只使用 PostCSS 可以避免这种情况。

    ¥No quirks or workarounds. Because Tailwind adds some new non-standard keywords to CSS (like @tailwind, @apply, theme(), etc.), you often have to write your CSS in annoying, unintuitive ways to get a preprocessor to give you the expected output. Working exclusively with PostCSS avoids this.

有关可用 PostCSS 插件的相当全面的列表,请参阅 PostCSS GitHub 存储库,但这里有一些我们在自己的项目中使用并可以推荐的重要插件。

¥For a fairly comprehensive list of available PostCSS plugins see the PostCSS GitHub repository, but here are a few important ones we use on our own projects and can recommend.

构建时导入

¥Build-time imports

预处理器提供的最有用的功能之一是能够将 CSS 组织到多个文件中,并在构建时通过提前处理 @import 语句而不是在浏览器中将它们组合起来。

¥One of the most useful features preprocessors offer is the ability to organize your CSS into multiple files and combine them at build time by processing @import statements in advance, instead of in the browser.

使用 PostCSS 处理此问题的规范插件是 postcss-import

¥The canonical plugin for handling this with PostCSS is postcss-import.

要使用它,请通过 npm 安装插件:

¥To use it, install the plugin via npm:

npm install -D postcss-import

然后将它添加为 PostCSS 配置中的第一个插件:

¥Then add it as the very first plugin in your PostCSS configuration:

// postcss.config.js
module.exports = {
  plugins: {
    'postcss-import': {},
    tailwindcss: {},
    autoprefixer: {},
  }
}

关于 postcss-import 需要注意的一件重要事情是它严格遵守 CSS 规范并且不允许在文件的最顶部以外的任何地方使用 @import 语句。

¥One important thing to note about postcss-import is that it strictly adheres to the CSS spec and disallows @import statements anywhere except at the very top of a file.

行不通,@import 语句必须放在第一位

/* components.css */

.btn {
  padding: theme('spacing.4') theme('spacing.2');
  /* ... */
}

/* Will not work */
@import "./components/card";

这个问题最简单的解决方案是永远不要在同一个文件中混合使用常规 CSS 和导入。相反,为你的导入创建一个主要的入口点文件,并将所有实际的 CSS 保存在单独的文件中。

¥The easiest solution to this problem is to never mix regular CSS and imports in the same file. Instead, create one main entry-point file for your imports, and keep all of your actual CSS in separate files.

使用单独的文件进行导入和实际 CSS

/* components.css */
@import "./components/buttons.css";
@import "./components/card.css";
/* components/buttons.css */
.btn {
  padding: theme('spacing.4') theme('spacing.2');
  /* ... */
}
/* components/card.css */
.card {
  padding: theme('spacing.4');
  /* ... */
}

你最有可能遇到这种情况的地方是包含 @tailwind 声明的主 CSS 文件。

¥The place you are most likely to run into this situation is in your main CSS file that includes your @tailwind declarations.

行不通,@import 语句必须放在第一位

@tailwind base;
@import "./custom-base-styles.css";

@tailwind components;
@import "./custom-components.css";

@tailwind utilities;
@import "./custom-utilities.css";

你可以通过为每个 @tailwind 声明创建单独的文件,然后将这些文件导入你的主样式表来解决这个问题。为方便起见,我们为每个开箱即用的 @tailwind 声明提供单独的文件,你可以直接从 node_modules 导入这些文件。

¥You can solve this by creating separate files for each @tailwind declaration, and then importing those files in your main stylesheet. To make this easy, we provide separate files for each @tailwind declaration out of the box that you can import directly from node_modules.

postcss-import 插件足够智能,可以自动查找 node_modules 文件夹中的文件,因此你不需要提供整个路径 - 例如 "tailwindcss/base" 就足够了。

¥The postcss-import plugin is smart enough to look for files in the node_modules folder automatically, so you don’t need to provide the entire path — "tailwindcss/base" for example is enough.

导入我们提供的 CSS 文件

@import "tailwindcss/base";
@import "./custom-base-styles.css";

@import "tailwindcss/components";
@import "./custom-components.css";

@import "tailwindcss/utilities";
@import "./custom-utilities.css";

嵌套

¥Nesting

为了添加对嵌套声明的支持,我们推荐我们打包的 tailwindcss/nesting 插件,它是一个 PostCSS 插件,它封装 postcss-nestedpostcss-nesting 并充当兼容层,以确保你选择的嵌套插件正确理解 Tailwind 的自定义语法。

¥To add support for nested declarations, we recommend our bundled tailwindcss/nesting plugin, which is a PostCSS plugin that wraps postcss-nested or postcss-nesting and acts as a compatibility layer to make sure your nesting plugin of choice properly understands Tailwind’s custom syntax.

它直接包含在 tailwindcss 包本身中,所以要使用它,你需要做的就是将它添加到你的 PostCSS 配置中,在 Tailwind 之前的某个地方:

¥It’s included directly in the tailwindcss package itself, so to use it all you need to do is add it to your PostCSS configuration, somewhere before Tailwind:

// postcss.config.js
module.exports = {
  plugins: {
    'postcss-import': {},
    'tailwindcss/nesting': {},
    tailwindcss: {},
    autoprefixer: {},
  }
}

默认情况下,它使用引擎盖下的 postcss-nested 插件,它使用类似 Sass 的语法,是支持 Tailwind CSS 插件 API 中嵌套的插件。

¥By default, it uses the postcss-nested plugin under the hood, which uses a Sass-like syntax and is the plugin that powers nesting support in the Tailwind CSS plugin API.

如果你更愿意使用 postcss-nesting(基于标准 CSS 嵌套 规范),请首先安装插件:

¥If you’d rather use postcss-nesting (which is based on the standard CSS Nesting specification), first install the plugin:

npm install -D postcss-nesting

然后将插件本身作为参数传递给 PostCSS 配置中的 tailwindcss/nesting

¥Then pass the plugin itself as an argument to tailwindcss/nesting in your PostCSS configuration:

// postcss.config.js
module.exports = {
  plugins: {
    'postcss-import': {},
    'tailwindcss/nesting': 'postcss-nesting',
    tailwindcss: {},
    autoprefixer: {},
  }
}

如果出于某种原因你需要使用非常特定的 postcss-nested 版本并且想要覆盖我们与 tailwindcss/nesting 本身打包在一起的版本,这也会很有帮助。

¥This can also be helpful if for whatever reason you need to use a very specific version of postcss-nested and want to override the version we bundle with tailwindcss/nesting itself.

请注意,如果你在项目中使用 postcss-preset-env,则应确保禁用嵌套并让 tailwindcss/nesting 为你处理:

¥Note that if you are using postcss-preset-env in your project, you should make sure to disable nesting and let tailwindcss/nesting handle it for you instead:

// postcss.config.js
module.exports = {
  plugins: {
    'postcss-import': {},
    'tailwindcss/nesting': 'postcss-nesting',
    tailwindcss: {},
    'postcss-preset-env': {
      features: { 'nesting-rules': false },
    },
  }
}

变量

¥Variables

现在 CSS 变量(正式名称为自定义属性)具有非常好的 浏览器支持,因此你根本不需要预处理器即可使用变量。

¥These days CSS variables (officially known as custom properties) have really good browser support, so you don’t need a preprocessor to use variables at all.

:root {
  --theme-color: #52b3d0;
}

/* ... */

.btn {
  background-color: var(--theme-color);
  /* ... */
}

我们在 Tailwind 本身内部广泛使用 CSS 变量,因此如果你可以使用 Tailwind,则可以使用原生 CSS 变量。

¥We use CSS variables extensively within Tailwind itself, so if you can use Tailwind, you can use native CSS variables.

你可能还会发现,你过去使用变量的大部分事情都可以用 Tailwind 的 theme() 函数代替,它使你可以直接在 CSS 中访问 tailwind.config.js 文件中的所有设计标记:

¥You may also find that most of the things you’ve used variables for in the past can be replaced with Tailwind’s theme() function, which gives you access to all of your design tokens from your tailwind.config.js file directly in your CSS:

.btn {
  background-color: theme('colors.blue.500');
  padding: theme('spacing.2') theme('spacing.4');
  /* ... */
}

了解有关 函数和指令文档theme() 功能的更多信息。

¥Learn more about the theme() function in our functions and directives documentation.

浏览器前缀

¥Vendor prefixes

要自动管理 CSS 中的浏览器前缀,你应该使用 Autoprefixer

¥For automatically managing vendor prefixes in your CSS, you should use Autoprefixer.

要使用它,请通过 npm 安装它:

¥To use it, install it via npm:

npm install -D autoprefixer

然后将它添加到 PostCSS 配置中插件列表的最后:

¥Then add it to the very end of your plugin list in your PostCSS configuration:

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  }
}

使用 Sass、Less 或 Stylus

¥Using Sass, Less, or Stylus

为了获得最佳的开发体验,我们强烈建议你 专门使用 PostCSS,并且不要在 Tailwind 项目中使用 Sass 或 Less 等预处理器。

¥For the best development experience, we highly recommend that you use PostCSS exclusively, and that you don’t use preprocessors like Sass or Less in your Tailwind projects.

要将 Tailwind 与 Sass、Less 或 Stylus 等预处理工具结合使用,你需要向项目添加一个额外的构建步骤,以允许你通过 PostCSS 运行预处理的 CSS。如果你在项目中使用 Autoprefixer,那么你已经设置了类似的东西。

¥To use Tailwind with a preprocessing tool like Sass, Less, or Stylus, you’ll need to add an additional build step to your project that lets you run your preprocessed CSS through PostCSS. If you’re using Autoprefixer in your project, you already have something like this set up.

请参阅我们关于 将 Tailwind 安装为 PostCSS 插件 的文档,了解有关将 Tailwind 集成到现有构建过程中的更多信息。

¥See our documentation on installing Tailwind as a PostCSS plugin to learn more about integrating Tailwind into your existing build process.

关于将 Tailwind 与预处理器一起使用,需要了解的最重要的一点是,Sass、Less 和 Stylus 等预处理器在 Tailwind 之前单独运行。这意味着你不能将 Tailwind 的 theme() 函数的输出提供给 Sass 颜色函数,因为在你的 Sass 被编译为 CSS 并提供给 PostCSS 之前,theme() 函数实际上并没有被评估。

¥The most important thing to understand about using Tailwind with a preprocessor is that preprocessors like Sass, Less, and Stylus run separately, before Tailwind. This means that you can’t feed output from Tailwind’s theme() function into a Sass color function for example, because the theme() function isn’t actually evaluated until your Sass has been compiled to CSS and fed into PostCSS.

不行,先处理 Sass

.alert {
  background-color: darken(theme('colors.red.500'), 10%);
}

除此之外,一些预处理器在与 Tailwind 一起使用时会出现一些问题,下面列出了解决方法。

¥Aside from that, some preprocessors have quirks when used with Tailwind, which are outlined with workarounds below.

Sass

将 Tailwind 与 Sass 结合使用时,将 !important@apply 结合使用需要使用插值才能正确编译。

¥When using Tailwind with Sass, using !important with @apply requires you to use interpolation to compile properly.

行不通,Sass 抗诉 !important

.alert {
  @apply bg-red-500 !important;
}

使用插值作为解决方法

.alert {
  @apply bg-red-500 #{!important};
}

除此之外,Sass 无法使用 Tailwind 的 screen() 函数,除非用括号括起来。

¥In addition to this, Sass has trouble with Tailwind’s screen() function unless wrapped in parentheses.

不起作用,Sass 会产生错误

@media screen(md) {
  .foo {
    color: blue;
  }
}

将 screen() 函数括在括号中

@media (screen(md)) {
  .foo {
    color: blue;
  }
}

从技术上讲,这会导致媒体查询周围出现一组额外的括号,但它仍然有效。

¥Technically this results in an extra set of parentheses around your media query, but it still works.

Stylus

将 Tailwind 与 Stylus 结合使用时,如果不将整个 CSS 规则封装在 @css 中,则无法使用 Tailwind 的 @apply 功能,以便 Stylus 将其视为字面量 CSS。

¥When using Tailwind with Stylus, you can’t use Tailwind’s @apply feature without wrapping the entire CSS rule in @css so that Stylus treats it as literal CSS.

Stylus 抗诉 @apply 不起作用

.card {
  @apply rounded-lg bg-white p-4
}

使用 @css 避免作为 Stylus 进行处理

@css {
  .card {
    @apply rounded-lg bg-white p-4
  }
}

然而,这会带来巨大的成本,即你无法在 @css 块内使用任何 Stylus 功能。

¥This comes with a significant cost however, which is that you cannot use any Stylus features inside a @css block.

另一种选择是使用 theme() 函数而不是 @apply,并以长格式写出实际的 CSS 属性:

¥Another option is to use the theme() function instead of @apply, and write out the actual CSS properties in long form:

使用 theme() 而不是 @apply

.card {
  border-radius: theme('borderRadius.lg');
  background-color: theme('colors.white');
  padding: theme('spacing.4');
}

除此之外,Stylus 在使用 Tailwind 的 screen() 函数时会遇到问题,除非你使用插值并将其括在括号中。

¥In addition to this, Stylus has trouble with Tailwind’s screen() function unless you use interpolation and wrap it in parentheses.

不起作用,Stylus 会生成错误

@media screen(md) {
  .foo {
    color: blue;
  }
}

使用插值和括号作为解决方法

@media ({'screen(md)'}) {
  .foo {
    color: blue;
  }
}

从技术上讲,这会导致媒体查询周围出现一组额外的括号,但它仍然有效。

¥Technically this results in an extra set of parentheses around your media query, but it still works.