TailwindCSS和UnoCSS

在近些年,原子化CSS越来越流行,我以前一直用的都是TailwindCSS,最近发现了另一个原子化CSS框架UnoCSS,于是很好奇,究竟什么时候使用TailwindCSS,什么时候使用UnoCSS。

原子化CSS

我很早就知道了TailwindCSS,但正式开始使用却是在2023年,因为我们公司的设计图是上传到了蓝湖,而蓝湖没有直接展示TailwindCSS代码的功能,直到我2023年底写了一个CSS转TailwindCSS的脚本,这个时候我才开始正式使用TailwindCSS。

一旦使用就停不下来了,使用原始的CSS写代码时,总是要为了class命名而烦恼,之前我接触到了一个CSS命名规范,叫做BEM,这个规范的命名方式是:

.block__element--modifier

这个命名方式的含义是:

  • block:块级元素
  • element:元素
  • modifier:修饰符

这个命名方式的优点是:

  • 命名规范,易于维护
  • 可读性强,易于理解
  • 可复用性强,易于重用

但是,这个命名方式的缺点是:

  • 命名冗长,不易记忆
  • 不易维护,不易扩展
  • 不易重用,不易复用

而如果使用Sass,那么上面的命名方式就变成了:

.block {
  &__element {
    &--modifier {

这种命名虽然写的时候非常方便,但是如果一旦出现了UI问题,要修改部分class对应的样式,那么普通的编辑器非常难以找到class对应的样式,因为无法通过点击class来定位到对应的样式代码。

而且使用传统的CSS,往往要删除一个功能的时候会留下大量的CSS冗余代码,因为删除了DOM,但不知道该DOM对应了哪些CSS代码。

使用传统CSS还有另一个缺陷,就是如果有一个需求需要创建一个新界面,而这个界面和已有的界面非常相似,那么复制DOM的时候就很难找到DOM对应的class,复制起来的时候就比较棘手。

而使用原子化CSS,这些问题就迎刃而解了,因为原子化CSS和DOM结构是紧密结合的,所以删除DOM的时候,对应的CSS代码也会被删除,复制的时候,复制对应DOM的时候就会把对应的CSS代码也复制过去。

比如下面的HTML代码:

<div class="block">
  <div class="block__element">
    <div class="block__element--modifier">

对应的CSS代码:

.block {
  width: 100px;
  height: 100px;
  background-color: red;

  &__element {
    width: 100px;
    height: 100px;
    &--modifier {
      width: 100px;
      height: 100px;
    }
  }
}

如果使用原子化CSS,那么上面的HTML代码就会变成:

<div class="w-100 h-100 bg-red-500">
  <div class="w-100 h-100">
    <div class="w-100 h-100">
    </div>
  </div>
</div>

可以看出,原子化CSS的class命名非常简洁,易于维护,易于扩展,易于重用。

TailwindCSS

TailwindCSS是原子化CSS的一种实现,它是现在最流行的原子化CSS框架。

在3.x版本后,它支持了w-[60px]这种写法,这种写法可以不预先在tailwind.config.js中写对应的配置,直接就可以写对应的样式,这就让TailwindCSS发生了质变,因为为了满足UI设计图,往往TailwindCSS已经存在的类名不能够满足需求,需要自己写对应的配置,而3.x版本后,就不需要了。

通过网上已经有的CSS转TailwindCSS库,例如我自己使用的:css-to-tailwind,就可以把CSS代码转换成TailwindCSS代码。

同时配合我之前写的编写油猴脚本的方法制作油猴Tampermonkey脚本需要哪些知识,就可以很轻易地编写出一个将蓝湖的CSS代码转换成TailwindCSS代码的脚本。

TailwindCSS 4.x

TailwindCSS 4.x 用了Rust重写了编译器,所以编译速度比3.x版本快了很多,但是它也带来了一些问题,它用了更新的CSS语法,所以对于浏览器版本要求更高,同时运行它也需要依赖Rust环境,如果没有Rust环境,那么会报错。

所以我在发现了这些问题后还是退回了3.x版本。

UnoCSS

UnoCSS是一个即时按需的原子化CSS引擎,由Windi CSS团队成员,特别是Anthony Fu开发。UnoCSS可以被视为Windi CSS的”精神继承者”,因为Windi CSS已经在2023年3月停止维护。

UnoCSS的起源

Anthony Fu在开发Vitesse(一个流行的Vite启动模板)时,发现使用TailwindCSS会导致Vite的启动和热更新变慢,因为TailwindCSS会生成大量的工具类CSS。后来他发现了Windi CSS,一个从零开始编写的TailwindCSS替代方案,具有零依赖性,不依赖PostCSS和Autoprefixer,最重要的是,它具有按需使用的特性。

Windi CSS发展得很好,团队推出了许多创新功能,如值推断、变体组、快捷方式、DevTools中的设计、属性模式等。这促使Tailwind也不得不引入自己的按需JIT引擎。

最终,Anthony Fu从Windi CSS的经验中受到启发,创建了UnoCSS,作为一个更加灵活、可扩展且高性能的原子化CSS引擎。

UnoCSS与Windi CSS和TailwindCSS的区别

UnoCSS与Tailwindcss的最大区别是,它没有像Tailwindcss一样预设类名,而是通过插件系统来动态生成类名。这种设计使UnoCSS更加灵活,因为UI设计通常并不遵循TailwindCSS的设计规范,我们在实际项目中经常需要使用w-[60px]这种自定义写法。

UnoCSS不仅兼容了TailwindCSS的写法,其编译速度比TailwindCSS快数十倍,并且拥有比TailwindCSS更强大的插件系统。根据官方文档,UnoCSS的特点包括:

  • 完全可定制 - 没有核心工具类,所有功能通过预设提供
  • 无解析、无AST、无扫描,它是即时的(比Windi CSS或Tailwind JIT快5倍)
  • 约6kb的最小压缩体积 - 零依赖且浏览器友好
  • 快捷方式 - 动态别名工具类
  • 属性化模式 - 在属性中分组工具类
  • 纯CSS图标 - 将任何图标作为单个类使用
  • 变体组 - 为具有共同前缀的工具类提供简写
  • CSS指令 - 使用@apply指令在CSS中重用工具类
  • 编译模式 - 在构建时将多个类合成为一个
  • 检查器 - 交互式检查和调试
  • CSS-in-JS运行时构建 - 通过一行CDN导入使用UnoCSS
  • VS Code扩展
  • CSS代码拆分 - 为多页应用程序提供最小的CSS

这些特性使UnoCSS成为一个强大且灵活的工具,适用于各种前端开发场景。

UnoCSS的小程序支持

UnoCSS对小程序的兼容性非常好,它拥有一个unocss-preset-weapp插件,可以让我们在小程序中使用UnoCSS。

而TailwindCSS如果要兼容小程序,也拥有非常多的兼容性插件可以选择,比如说:weapp-tailwindcss

兼容性

TailwindCSS 3.x只能运行在PostCSS 8.x版本,而如果你用的是Vue CLI 4.x版本,那么你安装的PostCSS版本是7.x版本,所以你不能直接使用TailwindCSS 3.x版本。

经过我很多次努力想要将项目的Vue CLI升级到5.x版本,但是都失败了,因为升级Vue CLI后会遇到各种各样的问题。这种情况下可以考虑使用UnoCSS,因为它不依赖PostCSS。

总结

其实我推荐大部分情况下还是使用TailwindCSS,因为它的生态非常成熟,而且它从2019年开始慢慢变得越来越流行,现在的周下载量已经达到了1000万+。虽然UnoCSS作为Windi CSS的精神继承者有很多优势,但由于没有TailwindCSS那么广泛采用,停止维护的风险比TailwindCSS要大。

不过,考虑到UnoCSS由Anthony Fu(Vite团队成员)主导开发,并且在GitHub上已经获得了超过17.2k的星标,展现了强劲的社区支持,所以它的发展前景仍然非常乐观。

如果是新建的项目,那几乎都会使用最新的框架,所以TailwindCSS是最佳选择。

如果项目中需要使用小程序,那么UnoCSS是最佳选择,因为它的灵活写法,可以让我们在小程序中更加方便地使用。

同样,如果你的项目受到PostCSS版本限制,或者需要极致的编译性能,UnoCSS也是一个很好的选择。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!