Tailwind CSS 使用预处理器

2022-07-25 17:38 更新

使用预处理器

一个使用 Tailwind 与常见的 CSS 预处理器,如 Sass,Less 和 Stylus 的指南


由于 Tailwind 是一个 PostCSS 插件,没有什么可以阻止您使用 Sass,Less,Stylus 或其他预处理器,就像您可以使用其他 PostCSS 插件,如 Autoprefixer

重要的是要注意,您不需要在Tailwind中使用预处理器—您通常在 Tailwind 项目中写很少的 CSS,所以使用预处理器并不像在一个您写了很多自定义 CSS 的项目中那样有利。

本指南只是作为一个参考,供那些需要或想将 Tailwind 与预处理器整合的人使用。

使用PostCSS作为您的预处理器

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

这有几个好处。

  • 您的构建速度会更快。因为您的 CSS 不需要被多个工具解析和处理,所以只使用 PostCSS,您的 CSS 会编译得更快。
  • 因为 Tailwind 添加了一些新的非标准关键字到 CSS 中(如​@tailwind​, ​@apply​, ​theme()​等),您经常不得不用烦人的,不直观的方式来写您的 CSS,以得到一个预处理器给您预期的输出。而使用 PostCSS 则可以避免这种情况。

关于可用的 PostCSS 插件,请参见 PostCSS GitHub repository,但这里有几个重要的插件,我们在自己的项目中使用,并且可以推荐。

构建时导入

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

用于处理 PostCSS 的规范插件是 postcss-import

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

npm install postcss-import

然后把它作为 PostCS 配置中的第一个插件:

// postcss.config.js
module.exports = {
  plugins: [
    require('postcss-import'),
    require('tailwindcss'),
    require('autoprefixer'),
  ]
}

关于 ​postcss-import​,需要注意的一个重要问题是,它严格遵守 CSS 规范,不允许在任何地方使用 ​@import​ 语句,除非在文件的顶部。

无法工作,@import 语句必须放在第一位。

/* components.css */

.btn {
  @apply px-4 py-2 rounded font-semibold bg-gray-200 text-black;
}

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

解决这个问题最简单的方法就是永远不要在同一个文件中混合常规 CSS 和导入。取而代之的是,为您的导入文件创建一个主入口文件,并将所有实际的 CSS 保存在单独的文件中。

为导入和实际的 CSS 使用单独的文件。

/* components.css */
@import "./components/buttons.css";
@import "./components/card.css";
/* components/buttons.css */
.btn {
  @apply px-4 py-2 rounded font-semibold bg-gray-200 text-black;
}
/* components/card.css */
.card {
  @apply p-4 bg-white shadow rounded;
}

您最可能遇到这种情况的地方是在您的主 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 文件

您可以通过把您的 ​@tailwind​ 声明放在他们自己的文件中来解决这个问题。为了方便,我们为每个 ​@tailwind​ 声明提供了单独的文件,您可以直接从 ​node_modules​ 导入。

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

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

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

嵌套

要添加对嵌套声明的支持,我们推荐我们捆绑的 ​tailwindcss/nesting​ 插件,这是一个 PostCSS 插件,它包装了 postcss-nested 或 postcss-nesting 并充当兼容层,以确保您选择的嵌套插件正确理解 Tailwind 的自定义语法,例如​@apply​ 和 ​@screen​。

它直接包含在 ​tailwindcss ​包本身中,因此要使用它,您只需将其添加到 PostCSS 配置中,位于 Tailwind 之前的某个位置:

// postcss.config.js
module.exports = {
  plugins: [
    require('postcss-import'),
    require('tailwindcss/nesting'),
    require('tailwindcss'),
    require('autoprefixer'),
  ]
}

默认情况下,它在后台使用 postcss-nested 插件,该插件使用类似 Sass 的语法,并且是 Tailwind CSS 插件 API 中支持嵌套支持的插件。

如果你更喜欢使用 postcss-nesting(它基于工作中的 CSS 嵌套规范),首先安装插件:

npm install postcss-nesting

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

// postcss.config.js
module.exports = {
  plugins: [
    require('postcss-import'),
    require('tailwindcss/nesting')(require('postcss-nesting')),
    require('tailwindcss'),
    require('autoprefixer'),
  ]
}

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

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

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

变量

如今,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');
  /* ... */
}

供应商前缀

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

要使用它,请通过 npm 安装它:您可以使用 postcss-preset-env 插件为您的项目添加对即将到来的 CSS 特性的支持。

npm install autoprefixer

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

module.exports = {
  plugins: [
    require('tailwindcss'),
    require('autoprefixer'),
  ]
}

使用 Sass、Less 或 Stylus

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

确切的说明将取决于您使用的构建工具,所以请参阅我们的安装文档来了解更多关于将 Tailwind 整合到您现有的构建过程中。

关于使用 Tailwind 与预处理器的最重要的事情是,预处理器,如Sass,Less和Stylus单独运行,在Tailwind之前。这意味着您不能将 Tailwind 的​theme()​函数的输出输入到 Sass 颜色函数中,例如,因为 ​theme()​ 函数在您的 Sass 被编译成 CSS 并输入 PostCSS 之前不会被实际评估。

不行,Sass先被处理

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

为了获得最有凝聚力的开发体验,建议您专门使用 ​PostCSS ​。

除此之外,每个预处理器在与 Tailwind 一起使用时,都有自己的一两个怪癖,下面用变通方法概述一下。

Sass

当使用Sass的 Tailwind 时,使用 ​!important 与 ​@apply​ 需要您使用插值来正确编译。

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

使用插值作为解决方法

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

Less

当使用 Tailwind 和 Less 一起使用时,您不能嵌套 Tailwind 的 ​@screen​ 指令。

无法工作,Less 无法检查到这是一个媒体查询

.card {
  @apply rounded-none;

  @screen sm {
    @apply rounded-lg;
  }
}

取而代之的是,使用常规的媒体查询和 theme() 函数来引用您的屏幕尺寸,或者干脆不要嵌套您的@screen指令。

使用常规的媒体查询和 theme()

.card {
  @apply rounded-none;

  @media (min-width: theme('screens.sm')) {
    @apply rounded-lg;
  }
}

在顶层使用 @screen 指令

.card {
  @apply rounded-none;
}
@screen sm {
  .card {
    @apply rounded-lg;
  }
}

Stylus

当使用 Tailwind 和 Stylus 时,您不能使用 Tailwind的 ​@apply​ 功能,如果不把整个 CSS 规则包裹在 ​@css​ 中,那么 Stylus 就会把它当作字面 CSS。

无法工作,Stylus 与 @apply 冲突

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

使用 @css 来避免被 Stylus 处理

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

然而,这有一个重要的代价,那就是您不能在 ​@css​ 块中使用任何 Stylus 功能。

另一个选择是使用 ​theme()​ 函数代替 ​@apply​,并以长格式写出实际的 CSS 属性。

使用 theme() 代替 @apply

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

除此之外,Stylus 不支持嵌套 ​@screen​ 指令(就像 Less 一样)。

无法工作,Stylus 检查不出这是一个媒体查询

.card {
  border-radius: 0;

  @screen sm {
    border-radius: theme('borderRadius.lg');
  }
}

取而代之的是,使用常规的媒体查询和 ​theme()​ 函数来引用您的屏幕尺寸,或者干脆不要嵌套您的 ​@screen​ 指令。

使用常规的媒体查询和 theme()

.card {
  border-radius: 0;

  @media (min-width: theme('screens.sm')) {
    border-radius: theme('borderRadius.lg');
  }
}

在顶层使用 @screen 指令

.card {
  border-radius: 0;
}
@screen sm {
  .card {
    border-radius: theme('borderRadius.lg');
  }
}


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号