UnoCSS是一款原子化的即时按需 CSS 引擎,其中没有核心实用程序,所有功能都是通过预设提供的。默认情况下UnoCSS应用通过预设来实现相关功能。
UnoCSS中文文档:

前有很多种原子化的框架,例如 Tailwind CSS,Windi CSS 以及 Tachyons 等。
为什么要原子化 CSS?
- 不知道怎么取类名,应该叫什么名字呢,该怎么统一
- CSS页面样式太多,每次一个页面要新写一个重复类,自己都不记得有哪些类了
- Style文件和页面文件来回反复横跳新增全局样式,太麻烦
传统方式可能会使用比如 scss 预处理器生成自己想要的 class 类,如下所示:
css
@for $i from 1 through 10 {
.m-#{$i} {
margin: $i px;
}
}
// 结果为:
.m-1 { margin: 1 px; }
.m-2 { margin: 2 px; }
/* ... */
.m-10 { margin: 10 px; }
上述方式会产生很多场景下可用的 class,可以涵盖很多场景,但是其中也会有很多种并不会被使用到,从而了导致大量的冗余;因此原子化 CSS 中对于这个也进行了优化,通过按需加载的理念进行预设等方式减少 CSS 的打包体积;
相比原始写法,应用原子化 CSS 可以减少很多 CSS 的书写工作,减少每次新增一个新的样式而重复新增的代码,比如一个项目中 flex 和 margin 配置一般都会重复写很多次,使用原子化 CSS 不用重新去写这些样式,直接绑定相对应的 class 类名就可以起到同样的效果,因此减少了项目整体的代码行数量和无用的工作量。
总的来说原子化 CSS 可以减少 CSS 的体积,同时提高 CSS 类的复用率,减少类名起名的复杂度;但是由于多种 CSS 样式堆积,可能会造成 class 名过长的缺点;同时增加记住 CSS 样式的记忆成本;
那么目前哪些人在使用原子化 CSS 呢?
一些网站已经开始使用原子化 CSS 比如 github , swiper.js 等↓如下图所示,他们页面的 CSS 类型可以明显看出是使用了原子化 CSS
一种原子化 CSS 框架 - UnoCss
UnoCSS 是一个引擎,而非一款框架,因为它并未提供核心工具类,所有功能可以通过预设和内联配置提供;
UnoCSS 中文官网链接 : www.unocss.com.cn/
原子化 CSS 的概念
所谓 原子化 CSS ,指的是一种用于CSS的架构方式的理念,它倾向于 用途单一的 class,并 以视觉效果进行命名。例如 bootstrap 的颜色系统,为我们提供了直观的颜色名称: 我们可以将这些名称以相似的命名方式构建 css 类:
css
// Background color
.bg-blue-100 { background-color: $blue-100 }
.bg-blue-200 { background-color: $blue-200 }
.bg-blue-300 { background-color: $blue-300 }
.bg-blue-400 { background-color: $blue-400 }
.bg-blue-500 { background-color: $blue-500 }
.bg-blue-600 { background-color: $blue-600 }
.bg-blue-700 { background-color: $blue-700 }
.bg-blue-800 { background-color: $blue-800 }
.bg-blue-900 { background-color: $blue-900 }
// Font color
.ft-blue-100 { color: $blue-100 }
.ft-blue-200 { color: $blue-200 }
.ft-blue-300 { color: $blue-300 }
.ft-blue-400 { color: $blue-400 }
.ft-blue-500 { color: $blue-500 }
.ft-blue-600 { color: $blue-600 }
.ft-blue-700 { color: $blue-700 }
.ft-blue-800 { color: $blue-800 }
.ft-blue-900 { color: $blue-900 }
// margin
.m-1 { margin: 0.25 rem; }
.m-2 { margin: 0.5 rem; }
.m-3 { margin: 0.75 rem; }
.m-4 { margin: 1 rem; }
.m-5 { margin: 1.25 rem; }
.m-6 { margin: 1.5 rem; }
.m-7 { margin: 1.75 rem; }
.m-8 { margin: 2 rem; }
.m-9 { margin: 2.25 rem; }
我们可以很直观地使用和调整这些变量值来满足我们实际开发中的需求,同时我们可以通过动控制 DOM 的样式来轻松地对效果进行切换,这在 一些现代前端框架(如vue)中,都可以有很丝滑的体验。
这个例子中的变量为 scss/sass(Sass) 变量,Sass 是目前最强大的前端样式预编译语言,本文在后文中也会有一些涉及它的内容。如果你只会 css,或者还在使用 Less(另一种流行的预编译语言),那么建议你尽早学一下 scss 语法,这十分强大方便,bootstrap、elementPlus 等等多数当前主流框架早以切换到其构建样式系统。
为什么推荐原子化 CSS
那么为什么要原子化呢。很显然是让代码更 直观可读。另外一方面,从设计师的角度出发,如果我们拿到下面这个语义化的外边距变量名:
css
.p-1 { margin: 0.25 rem; }
.p-2 { margin: 0.5 rem; }
/* ... */
.p-9 { margin: 2.25 rem; }
完全就可以对照着呈现效果自己手动更改变量来完成效果切换!
原子化 CSS 的实现实践
如何才能具备原子化的理念的,实现方法有很多。在一个大项目中为了原子化 CSS,。可以先 提供所有你可能需要用到的 CSS 工具,例如 外边距的大小工具------我们需要约定好一套规范,就像前面的代码那样,使用 p 表示 padding 的简写,使用 数字 1、2、3、... 表示基值的倍数,这里约定基值为 0.25 rem 。 很显然在现实项目中通过手动列举 CSS 类名并逐个描述来完成一套这样的约定是麻烦的,比如在这种情况下为了尽可能简单一点我们会使用 root 为元素中定义一些CSS变量------它们会在不同的原子类中反复用到:
css
:root {
--blue-100: #CEE1FE;
--blue-200: #9DC3FC;
--blue-300: #69A1F3;
--blue-400: #3C89FA;
--blue-500: #0D6DFB;
--blue-600: ##0A58CA;
--blue-700: #084297;
--blue-800: #052C65;
--blue-900: #031633;
--rsize-1: 0.25 rem;
--rsize-2: 0.5 rem;
--rsize-3: 0.75 rem;
--rsize-4: 1 rem;
--rsize-5: 1.25 rem;
--rsize-6: 1.5 rem;
--rsize-7: 1.75 rem;
--rsize-8: 2.00 rem;
--rsize-9: 2.25 rem;
}
然后施展原子css我们的优势了:
css
// Background color
.bg-blue-100 { background-color: var(--blue-100) }
.bg-blue-200 { background-color: var(--blue-200) }
// ...
.bg-blue-900 { background-color: var(--blue-200) }
// Font color
.ft-blue-100 { color: var(--blue-100) }
.ft-blue-200 { color: var(--blue-200) }
// ...
.ft-blue-900 { color: var(--blue-900) }
// Margin
.m-1 { margin: var(--rsize-1) }
.m-2 { margin: var(--rsize-1) }
// ...
.m-9 { margin: var(--rsize-9) }
使用预编译语言
这样是不是依然很麻烦------好在我们可以通过编程来完成。 由于 css 自身并没有这样的能力,以前不得不借助其它语言来生成这样的东西,但如今我们可以使用 如 Sass、Less 这样的预处理器来实现。例如生成 10 p-1、p-2、...、p-9,我们可以使用 @for 指令:
css
@for $i from 1 through 9 {
.m-#{$i} {
margin: $i / 4 rem;
}
}
上面的 @for 指令可以在限制的范围内重复输出格式,其语法格式为:
css
@for $var from <start> through <end> {
// ... style
}
或者
css
@for $var from <start> to <end> {
// ... style
}
其中: • var 是迭代变量,可以在块内通过 {var} 的格式来引用; • 当使用 through 时,条件范围包含 与 的值,而使用 to 时条件范围只包含 的值不包含 的值; • 必须是整数值。 对于颜色值的计算和处理要复杂一些,我们需要用到一些 Sass 内置的一些颜色处理函数,例如 mix、adjust-hue、change-color、scale-color、desaturate、transparentize等等
总结感受: 在使用 UnoCSS 的过程中,感受到了不用写 的快乐,不用来回穿插 CSS 文件和 VUE 文件,CSS 类名随手就写上,想要什么样式往上堆积就行,还不用去绞尽脑汁的去想起什么类名,带来了很多便捷的地方;但是也存在一定的困难点,就是会造成无法快速定位样式问题的困惑;