一个使用 Tailwind 与常见的 CSS 预处理器,如 Sass,Less 和 Stylus 的指南
由于 Tailwind 是一个 PostCSS 插件,没有什么可以阻止您使用 Sass,Less,Stylus 或其他预处理器,就像您可以使用其他 PostCSS 插件,如 Autoprefixer。
重要的是要注意,您不需要在Tailwind中使用预处理器--您通常在 Tailwind 项目中写很少的 CSS,所以使用预处理器并不像在一个您写了很多自定义 CSS 的项目中那样有利。
本指南只是作为一个参考,供那些需要或想将 Tailwind 与预处理器整合的人使用。
如果您在一个全新的项目中使用 Tailwind,并且不需要将它与任何现有的 Sass/Less/Stylus 样式表集成,您应该高度考虑依靠其他 PostCSS 插件来添加您所使用的预处理器功能,而不是使用一个单独的预处理器。
这有几个好处。
@tailwind
, @apply
, theme()
等),您经常不得不用烦人的,不直观的方式来写您的 CSS,以得到一个预处理器给您预期的输出。而使用 PostCSS 则可以避免这种情况。关于可用的 PostCSS 插件,请参见PostCSS GitHub repository,但这里有几个重要的插件,我们在自己的项目中使用,并且可以推荐。
预处理器提供的最有用的功能之一是能够将您的 CSS 组织成多个文件,并在构建时通过提前处理 @import
语句而不是在浏览器中结合它们。
用于处理 PostCSS 的规范插件是 postcss-import。
要使用它,请通过 npm 安装该插件:
# npm
npm install postcss-import
# yarn
yarn add 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
导入。
导入我们提供的 CSS 文件。
@import "tailwindcss/base";
@import "./custom-base-styles.css";
@import "tailwindcss/components";
@import "./custom-components.css";
@import "tailwindcss/utilities";
@import "./custom-utilities.css";
postcss-import
是足够聪明的,它会自动寻找 node_modules
文件夹中的文件,所以您不需要提供整个路径--比如 "tailwindcss/base"
就足够了。
要添加对嵌套声明的支持,您有两个选项:
要使用这些插件,请通过 npm 安装它们:
# npm
npm install postcss-nested # or postcss-nesting
# yarn
yarn add postcss-nested # or postcss-nesting
然后将它们添加到您的 PostCSS 配置中,在 Tailwind 本身之后,但在 Autoprefixer 之前:
// postcss.config.js
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('postcss-nested'), // or require('postcss-nesting')
require('autoprefixer'),
]
}
如今 CSS 变量(官方称为自定义属性)有非常好的浏览器支持,所以实际上您可能根本不需要变量的插件。
但是如果您需要支持 IE11,您可以使用postcss-custom-properties插件来自动为您的变量创建回退。
要使用它,请通过 npm 安装它。
# npm
npm install postcss-custom-properties
# yarn
yarn add postcss-custom-properties
然后把它添加到您的 PostCSS 配置中,在 Tailwind 本身之后,但在 Autoprefixer 之前:
// postcss.config.js
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('postcss-nested'),
require('postcss-custom-properties'),
require('autoprefixer'),
]
}
您可以使用 postcss-preset-env 插件为您的项目添加对即将到来的 CSS 特性的支持。
要使用它,请通过 npm 安装它:
# npm
npm install postcss-preset-env
# yarn
yarn add postcss-preset-env
然后把它添加到您的 PostCSS 配置中,在 Tailwind 本身之后的某个地方。
// postcss.config.js
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('postcss-preset-env')({ stage: 1 }),
]
}
需要注意的是,CSS 变量、嵌套和自动前缀都是开箱即用的,所以如果您使用 postcss-reset-env
,您不需要为这些功能添加单独的插件。
要使用 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的 Tailwind 时,使用!重要
与@apply
需要您使用插值来正确编译。
无法工作,Sass 与 !important 冲突
.alert {
@apply bg-red-500 !important;
}
{/ Use interpolation as a workaround
使用插值作为变通
:.alert {
@apply bg-red-500 #{!important};
}
当使用 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;
}
}
{/ Use the @screen directive at the top-level
在顶层使用 @screen 指令
.card {
@apply rounded-none;
}
@screen sm {
.card {
@apply rounded-lg;
}
}
当使用 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');
}
}