🌪️ tailwind4 如何兼容预处理器
背景
Tailwind4 带来的一个显著的技术偏见就是不再支持 sass 之类的预处理器。这使得如果想要享受 tailwind4 性能及其他福利,需要把大量样式文件重构成原生 CSS。这在部分项目是不可接受的。
上周处理了一个依赖 Nuxt UI 的项目的升级。Nuxt UI 和 tailwind 是强绑定关系,换句话说 tailwind 是必选项。这里简单说一下处理思路,只是一个可行方案,仅供参考,之后社区可能会有更成熟的解决方法。
项目代码结合使用了 sass 函数和 tailwind 的 @apply 指令,如下图示。
简单移除 SCSS 不是一种选择,所以希望能有一种这种的方法,既用上 tailwind4,又能让现有代码继续使用。
UnoCSS
UnoCSS 是一个原子化 CSS 引擎,在某种程度而言,他和 tailwind 是竞品关系。但是比 tailwind 更先进的一点体现在他的设计得非常灵活和可扩展,可以通过定义规则来支持各种用法,且包含转化器,可以解析并处理 @apply 等指令。
见 Presets Wind4,UnoCSS 支持 tailwind4 的语法和功能,并且可以无缝集成到 Nuxt 应用中。首先是安装 UnoCSS 并启用相应的 preset:
import presetWind4 from '@unocss/preset-wind4'
import { defineConfig } from 'unocss'
export default defineConfig({
presets: [
presetWind4(),
],
})
接下来启用转换器以便解析 scss 文件中的 @apply 指令。这样 @apply 中包含的 tailwind 类名能被正确解析并转换为样式代码,并在项目中生效。
import presetWind4 from '@unocss/preset-wind4'
+ import transformerDirectives from '@unocss/transformer-directives'
import { defineConfig } from 'unocss'
export default defineConfig({
+ transformers: [
+ transformerDirectives(),
+ ],
presets: [
presetWind4({
reset: false,
}),
],
})
不过仍然有一个问题,tailwind4 的样式重置和 UnoCSS 会起冲突,并且由于 Tailwind4 大量代码依赖原生的 CSS 层,优先级低于 UnoCSS 生成的样式,所以界面仍然是错乱的。
所以最后一步是 UnoCSS 生成的样式的优先级。首先开启 UnoCSS 的输出样式代码到 CSS Layer 功能。
export default defineConfig({
// ...
outputToCssLayers: true,
})
然后,在 main.css 或其他样式入口,降低 UnoCSS 的输出层优先级。默认 UnoCSS 输出到 default 层,所以在入口文件使用 layer 语法预先定义 default 层和 tailwind 层(base、component、utils)的优先级,如下代码。
@layer default, base, components, utilities;
重启项目,界面就正常了。接下来,等待 UnoCSS 化的 Nuxt UI,或者静候 tailwind 社区佳音吧。