入职第一周,我接了个新功能开发任务,正好有机会在项目里第一次上手 UnoCSS。 从引入、配置、实战使用到踩坑总结,这篇文章记录了我整个真实的使用过程,顺便分享一些经验和小技巧。
🧩 项目背景
我最近刚加入一家新公司,前端项目整体技术栈是 React + TypeScript + Vite,这次接手的新项目页面结构偏组件化,样式需求也不少。
公司之前在某些项目里尝试过 UnoCSS,但还没有大规模落地,这次正好借着新功能上线的机会,我也想趁机实战一把。 说实话,在真正动手用之前,我对原子化 CSS 一直有点抗拒:看着那一串串类名,总觉得乱,觉得"和写 style inline 没区别"。
不过这次我强行逼自己用上 UnoCSS,结果还挺香的。
🤔 为什么选择 UnoCSS?
虽然是新项目开发,样式量不算特别大,但要写得快、写得整洁、还要便于后续复用和维护,对样式方案的选择其实挺关键的。
调研阶段我也对比过几种方案:
样式方案 | 优点 | 缺点 |
---|---|---|
SCSS / Less | 成熟稳定,可自由写嵌套和变量 | 维护麻烦,类名容易重复,拆组件样式时要引入多个文件 |
CSS Modules | 样式隔离,适合组件化 | 类名仍需维护,重复样式不易复用 |
Tailwind CSS | 原子化、文档多、社区活跃 | 类名前缀多、需预定义主题、类名拼接繁琐 |
UnoCSS | 类名极简、按需生成、配置灵活 | 学习成本稍高,文档偏底层,踩坑多 |
最终我选择了 UnoCSS,原因主要有 3 点:
- 按需生成类名,无需手动维护样式文件,更贴合组件开发节奏;
- vite 插件方式接入,配置极其轻量,基本无需额外操作;
- 可高度定制,可以自己写规则,自定义 class 变得更加简单。
一句话总结:想写得快、样式简单、还能灵活扩展,就选 UnoCSS。
⚙️ UnoCSS 是怎么引入项目的?
因为项目用的是 Vite + React,使用了 pnpm 管理,接入 UnoCSS 基本不费劲,几步就搞定了。
安装依赖:
ts
pnpm add -D unocss
vite.config.ts 中添加插件:
ts
import UnoCSS from 'unocss/vite'
export default defineConfig({
plugins: [react(), UnoCSS()]
})
加几个常用 preset:
ts
import { presetUno, presetIcons } from 'unocss'
UnoCSS({
presets: [
presetUno(),
presetIcons()
]
})
我没有启用 attributify 模式,还是采用传统的 className
写法,这样团队其他人更容易接入。
💡 实际开发中怎么用?(Demo 示例)
UnoCSS 的写法跟 Tailwind 类似,但不需要提前扫描、构建就能直接生效,写起来轻松很多。
以下是我在 Demo 中使用 UnoCSS 的一些示例:
页面结构 + 样式一把梭
ts
<div className="p-4 bg-white rounded shadow-md flex items-center justify-between">
<span className="text-lg font-bold text-gray-800">标题</span>
</div>
按钮 hover 效果一把梭
ts
<button className="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
提交
</button>
响应式断点也拿捏
ts
<div className="text-sm sm:text-base md:text-lg lg:text-xl">
响应式文字大小
</div>
不用写 CSS 文件、也不需要维护类名、不担心污染,直接 className 组合就完事了。
除了常规写法外,UnoCSS 还支持非常强大的自定义规则,下面分享我项目中用到的一个实际例子。
✨ 自定义规则增强灵活性
UnoCSS 最让我惊喜的一点就是可以自定义规则。比如这次项目里有个地方要"多行文本省略",传统写法又臭又长。
我就直接在 uno.config.ts
里自定义了一个工具类:
ts
// uno.config.ts
export default defineConfig({
rules: [
// 多行文本截断工具类
[
/^text-truncate-(\d+)$/,
([, lines]) => ({
display: '-webkit-box',
'-webkit-line-clamp': lines,
'-webkit-box-orient': 'vertical',
overflow: 'hidden',
'text-overflow': 'ellipsis',
}),
],
],
})
用的时候也很丝滑:
ts
<p className="text-truncate-2">
这是一个超长段落,将会被两行截断,超出的部分显示省略号......
</p>
是不是比用 SCSS 写变量还方便?尤其适合这种一劳永逸型的通用样式。
🐞 踩过的几个坑
虽然整体体验很好,但真用起来还是遇到几个坑,给大家踩过一遍,避免你也翻车:
动态类名无效
UnoCSS 是通过静态分析来生成类名的,像这种写法是不会生效的:
ts
const size = 'lg'
return <div className={`text-${size}`}>文本</div>
解决方法是:
- 静态写死可能的值;
- 或配置
safelist
白名单:
ts
safelist: ['text-sm', 'text-md', 'text-lg', 'text-xl']
IDE 无法提示类名
默认情况下 VSCode 不会自动提示 UnoCSS 类名,尤其是没有启用 attributify 的时候。 建议安装 UnoCSS 官方插件,并启用对应配置,能大幅提升开发效率。
📌 使用感受总结
经过这一轮实战,我对 UnoCSS 有了更完整的认识:
优点
- 类名都是一眼能看懂的,看名字就知道样式;
- 上手快,写一个类就能出效果;
- 插件 preset 多,icons / shortcuts / web fonts 想用啥有啥;
- 自定义能力强,几行代码搞定通用样式。
注意点
- 动态类名需提前规划,避免运行时失效;
- 公共样式建议封成 shortcuts;
- 多人协作时需统一 className 命名习惯,不然易读性较差;
🤔 哪些场景适合用 UnoCSS?
- 新项目从 0 起步,组件化程度高
- 样式不重,但变化多,讲究效率的业务线
- 团队能接受原子化类名这种写法
不太推荐的场景:
- 老项目,已经铺了很多 SCSS 或 styled-components
- 项目超重 UI,自定义样式太复杂
- 团队成员完全没接触过原子化 CSS
✅ 最后总结
这次引入 UnoCSS 虽然只是新功能的一小步,但使用下来我真的觉得很爽:
- 写得快;
- 改得少;
- 样式干净不乱;
- 自定义很灵活。
跟 Tailwind 比,UnoCSS 更轻、更自由、更适合偏工程一点的团队。 如果你也在用 React + Vite,又想减少样式负担,真的可以试试看 UnoCSS。
如果你觉得这篇文章对你有帮助,欢迎点赞 👍、收藏 ⭐、评论 💬 让我知道你在看~ 我会持续更新 前端打怪笔记系列文章 ,👉 记得关注我,不错过每一篇干货更新!❤️