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 协议 ,转载请注明出处!