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

值得注意的是,你不需要在Tailwind中使用预处理器 ——无论如何,你通常在Tailwind项目上编写很少的CSS,所以使用预处理器并不像在编写大量自定义CSS的项目中那样有益。

本指南仅供因无法控制的原因需要将Tailwind与预处理器集成的人参考,而不是因为这是一种推荐做法。


使用PostCSS作为预处理器

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

这有几个好处:

  • 您的构建速度会更快。由于您的CSS不必由多个工具解析和处理,因此仅使用PostCSS即可更快地编译CSS。
  • 没有怪癖或变通方法。 因为Tailwind在CSS中添加了一些新的非标准关键字(如“@Tailwind”、“@apply”、“theme()”等),你经常不得不以恼人、不直观的方式编写CSS,让预处理器为你提供预期的输出。只使用PostCSS可以避免这种情况。

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

Build-time imports

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

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

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

npm install -D postcss-import

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

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

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

不起作用,“@import”语句必须放在第一位

/* components.css */

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

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

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

为导入和实际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');
  /* ... */
}

你最有可能遇到这种情况的地方是你的主CSS文件,其中包括你的“@tailwind”声明。

不起作用,“@import”语句必须放在第一位

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

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

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

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

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

导入我们提供的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/resting插件,这是一个包装PostCSS-nested的PostCSS插件或postcss嵌套并充当兼容层,以确保您选择的嵌套插件正确理解Tailwind的自定义语法。

它直接包含在“tailwindcss”包中,因此要使用它,您只需将其添加到Tailwind之前的PostCSS配置中即可:

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

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

如果你更喜欢使用postcss-nesting(基于标准CSS Nesting规范),首先安装插件:

npm install -D postcss-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/resting”本身捆绑的版本,这也会很有帮助。

请注意,如果您使用的是postcss preset env在你的项目中,你应该确保禁用嵌套,让tailwindcss/resting为你处理它:

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

Variables

如今,CSS变量(官方称为自定义属性)具有非常好的浏览器支持,所以你根本不需要预处理器来使用变量。

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

/* ... */

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

我们在Tailwind本身中广泛使用CSS变量,所以如果你能使用Tailwind,你可以使用原生CSS变量。

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

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

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

提供前缀 Vendor prefixes

为了在CSS中自动管理供应商前缀,您应该使用Autoprefixer.

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

npm install -D autoprefixer

然后将其添加到PostCSS配置中插件列表的末尾:

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

Using Sass, Less, or Stylus

为了获得最佳的开发体验,我们强烈建议您[仅使用PostCSS](#使用post-css作为预处理器),并且不要在Tailwind项目中使用Sass或Less等预处理器。

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

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

关于使用Tailwind和预处理器最重要的一点是,像Sass、Less和Stylus这样的预处理器在Tailwind之前是分开运行的。这意味着你不能将Tailwind的theme()函数的输出馈送到Sass的颜色函数中,例如,因为在你的Sass被编译成CSS并馈送到PostCSS之前,theme)函数实际上不会被计算。

不起作用,首先处理Sass

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

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

Sass

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

不起作用, Sass complains about !important

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

使用插值作为解决方法

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

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

不起作用, Sass will generate an error

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

screen()函数括在括号中

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

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

使用括号括住后,会生成如下代码,在一些低版本的浏览器中依然不工作

@media (screen and (min-width: 790px) ) {
  .foo {
    color: blue;
  }
}

Stylus

当在Stylus中使用Tailwind时,如果不将整个CSS规则包装在“@CSS”中,则无法使用Tailwind的“@apply”功能,以便Stylus将其视为文字CSS。

不起作用, Stylus complains about @apply

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

Use @css to avoid processing as Stylus

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

然而,这需要付出巨大的代价,那就是你不能在@css块内使用任何Stylus功能

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

Use theme() instead of @apply

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

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

不起作用, Stylus will generate an error

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

Use interpolation and parentheses as a workaround

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

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

使用括号括住后,会生成如下代码,在一些低版本的浏览器中依然不工作

@media (screen and (min-width: 790px) ) {
  .foo {
    color: blue;
  }
}