随着大前端的潮流兴起之后,样式的写法越来越多种多样。从最开始的scss、less这些取代css-loader的样式框架,到css in js的样式注入的解决方案,再到Tailwind原子化CSS。其中,UnoCss作为原子化CSS解决方案中一支异军突起的新秀,我在自己的项目中上手使用了一把,本文来记录一下这个样式方案的使用体验。
Quick Start
我在项目中使用的是Vite,可以用这个命令来添加npm包 `pnpm add -D unocss`
安装完成后,在vite.config.ts中配置
// vite.config.ts
import UnoCSS from 'unocss/vite'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
UnoCSS(),
],
})
最后,在`main.ts`中添加下面的导入语句
//main.ts
import 'uno.css'
这时候已经可以在项目中正常使用了,如果是刚开始接触原子化css的解决方案,可以在下面的两个网站搜索熟悉一下:
https://to-unocss.netlify.app/
https://unocss.dev/interactive/
使用UnoCSS默认的preset
UnoCSS是基于配置的一些规则和缩写来把写入标签的symbol转化成对应的css样式,每一套规则可以抽象成一个单独文件,在UnoCSS中被叫做preset。我们在main.ts导入UnoCSS后,就可以官方默认的一些原子化样式,目前官方社区还支持:Wind、Mini、Attributify、Web fonts等preset,可以快速导入使用。也可以制作属于你自己或者公司使用的preset,可以方便样式的复用。
@unocss/preset-uno作为官方的默认preset,包含了很多其他的原子化CSS框架的预设,例如:
.ml-3{ margin-left:0.75rem;}// TailwindCSS
.ms-2{ margin-inline-start:0.5rem;}// Bootstrap
.mt-10px{ margin-top:10px;}// WindiCSS
.ma4{ margin:1rem;}// Tachyons
在组件中有两种使用他们的方法
方法一:
// class中添加symbol,中间用空格分割
<div class="flex justify-center items-center">
<button class="border border-cyan border-solid border-rd-5 bg-#cfc">click!</button>
</div>
方法二:
// 添加symbol作为attribute,中间用空格分割
<div flex justify-center items-center>
<button border border-cyan border-solid border-rd-5 bg-#cfc>click!</button>
</div>
UnoCSS提供了一些有用的语法,例如可以使用 w-\[100%\]!
来表示{width: 100% !important}
,对于穿透覆盖一些封装组件样式非常有用。
自定义的配置
除了封装好的preset之外,我们可以封装自己定制化的preset,或者是只针对当前项目的一些配置。
UnoCSS有非常多的可配置项目,我在这里只介绍一下我使用的其中三种:
- theme
在我的理解中,这个是针对于theme切换而特化出来的,也可以用来配置一些全局变量,在配置文件的其他属性中使用。
theme: {
colors:
{
shinyRed:'var(--van-danger-color)',
layout: {
background:'var(--default-background-color)',
navcolor:'#fff',
},
},
},
在theme可以引用定义在全局css中的变量,这里我就使用了Vant组件库的变量`–van-danger-color` 以及我自定义的变量 `–default-background-color`
- rules
接下来我们可以在rules中定义一些复杂的规则,来匹配每个原子化的样式。例如,我在项目中借助theme定义的常量动态匹配symbol:
rules: [
[/^shiny-text(-[\w\(\-\)]+?)?(-[\w\(\)\-]+)?$/, (match, {rawSelector,theme })=> {
constselector=e(rawSelector)
if (!match[1]) {
return`${selector} {
border-style: none;
background-color:${theme.colors.layout.background};
-webkit-background-clip: text;
background-clip: text;
font-size: 5vw;
--un-text-opacity: 1;
color: rgb(0 0 0 / var(--un-text-opacity));
filter: drop-shadow(0 0 0.75rem var(--van-blue))
}`
}else if (!match[2]) {
return`${selector} {
border-style: none;
background-color:${theme.colors.layout.background};
-webkit-background-clip: text;
background-clip: text;
font-size: 5vw;
--un-text-opacity: 1;
color:${match[1].slice(1)};
filter: drop-shadow(0 0 0.75rem var(--van-blue))
}`
}else {
return`${selector} {
border-style: none;
background-color:${theme.colors.layout.background};
-webkit-background-clip: text;
background-clip: text;
font-size: 5vw;
--un-text-opacity: 1;
color:${match[1].slice(1)};
filter: drop-shadow(0 0 0.75rem${match[2].slice(1)})
}`
}
}],
]
- shortcut
对于一些没有这么复杂的原子化样式,例如,我需要在项目中大量使用白色的阴影卡片作为容器,这个时候我们就可以用到shortcut,来快捷应用这样的分子化样式:
shortcuts: [
// shortcuts to multiple utilities
['card','border-rd-30 bg-#FFFFFF shadow-[0px_6px_20px_0px_rgba(204,204,204,0.3)] w-100% mb-4vw p-2rem'],
]
结语
目前笔者对于UnoCSS的使用报告就是这些,还属于比较基础的探索阶段。待后续有了更深入地探索,会继续和大家进行分享。愿命运与你我同在!