本篇内容是记录,使用vite初始化vue3+ts的项目后将,原有的css替换为unocss的使用方式过程中遇到的一些问题,一些问题是通过同事的帮助,解决,一些问题是查阅文档或在issue搜索解决,记录下最终的解决办法,记录下来方便后面查阅,使用的开发工具是vscode
为项目添加unocss
- 安装模块
sh
npm i -D unocss
- 参照官方文档
vite
方式安装,也可参考vite-vue3 example
- 手动在根目录创建
unocss.config.ts
,添加如下内容
js
import { defineConfig } from 'unocss/vite';
import {
presetUno,
presetAttributify,
transformerDirectives,
transformerVariantGroup,
} from 'unocss';
export default defineConfig({
shortcuts: {
green: 'decoration-none transition-duration-0.4s c-[hsla(160,100%,37%,1)]',
},
presets: [presetUno(), presetAttributify()],
transformers: [transformerDirectives(), transformerVariantGroup()],
});
内容相对简单,以上内容的中的内容会在后续使用中遇到的问题及如何处理
说明
为vscode安装unocss插件
- 在vscode中安装vscode插件,根据文档配置好,找个组件添加一个
unocss
样式,如果样式正确会有虚下划线显示,鼠标放上去会出现如下计结果

- 根据unocss规则调整创建项目时的组件,不知道的规则可以在unocss interactive doc查询,如下图所示

使用中遇到的问题及如何处理
[]
的使用
在处理background-color: hsla(160, 100%, 37%, 0.2)
这个样式时,刚开始也是各种实验,都不成功,没办法用了自定义规则解决,但后来问了同事一下,这个种可以使用[]
处理,生成时会将[]
内的内容原封不动的使用,所以就可以这样写,c-[hsla(160,100%,37%,1)]
注意这里不能有空格。
提示 []
可能会产生部分重复问题,例如在替换dispaly: none
时,当时按照inline block
的思路首先想到的是none
,但是并没有成功,然后使用d-none
、display-none
等等一顿乱试,都没有成功,最后选择了display-[none]
,后来在unocss interactive doc查询其他规则时,无意间发现hidden
才是dispaly: none
。
$
的使用
在处理color: var(--color-text)
这种带有css变量的样式时,可以这样写c-$color-text
使用@media屏幕适配
在处理以下样式时
css
@media (min-width: 1024px) {
...
}
这个对于使用其他原子化css人来说可能比较熟悉,但对于初学者还不清除如何处理,这里可参考windicss,其实大多数时候都可以参考windicss 文档来写unocss ,这里也给出一下案例方便理解,其中lg 最终生成为@media (min-width: 1024px)
,这些都是预设自带的,也都可以根据自己需要自定义
html
<header
class="lh-normal max-h-screen"
lg="flex place-items-center pr-[calc(var(--section-gap)/2)]">
<img
class="block m-(x-auto b-2rem)"
lg="m-(t-2rem r-0 b-0 l-0)"
src="@/assets/logo.svg"
/>
<div lg-flex="~ wrap" lg="place-items-start">
<nav
class="w-100% text-(12px center) mt-2rem"
lg="text-(left, 1rem) m-(l--1rem t-1rem) p-(x-0 y-1rem)"
>
...
</nav>
</div>
</header>
quoted:
的使用
在使用伪元素(before、after之类)是,要为content设置内容,例如before-content-[123]
,当打开界面时发现界面上根本没有before
,但通过网站可以unocss interactive doc,可以匹配,如下所示:

通过上面匹配内容可以看到,content
值最终是个数字,也就是说这是个无效值了(MDN content),但要将123
最终为字符串时发现before-content-['123']
、before-content-["123"]
都不行,这时用到了quoted:
,正确做法为before-content-[quoted:123]
,这个解决方法是从issues 1820查到
_
的使用
在替换grid-template-columns: 1fr 1fr;
这个样式时,发现使用grid-cols-[1fr 1fr]
,这个规则无效,在浏览器的Styles
根本没有,使用grid-cols-[1fr1fr]
时,Styles
出来了,但是个错误的无效样式。这个在issues 1478中有提到,使用_
代替空格
prefix
前缀解决属性冲突
html
<div before="content-empty absolute left-0"></div>
上面内容在界面上无法正常编译出出伪元素
,这个也是百思不得其解,不知道问题到底出在哪了,后来请教了一下同事,可能是属性冲突了,尝试用un-before
替代before
,内容渲染正常了。在这里也做了其他尝试时,un-
为默认,不配置也可以用,如果需要加别的前缀需要在unocss.config.ts
中配置,prefix: 'un-',prefixedOnly: true, // <--
,具体参考参考:preset-attributify。
这里有个问题,为啥div
元素中before
会冲突
transformerDirectives
作用
在文章上面unocss.config.ts
中的shortcuts
有个green
属性,那个是替换公共样式,提取出来的,但这个样式会通用到所有的a
标签,这里需要在全局样式中为a
标签添加一个通用样式,这里就用了transformerDirectives
,当配置这个后我们就可以这样做:
css
a {
/* 用--at-apply而非@apply,因为后者在vscode没有语法加亮并且有个警告 */
--at-apply: green;
}
transformerVariantGroup
作用
使用原子化css有个比较明显的特点就是样式部分会比较长和多,这里有个小技巧就是使用transformerVariantGroup
来缩短书写和更清晰分辨,可以对比一下配置前和配置后的效果
- 配置前未压缩
html
<div class="text-center text-clip text-1rem"></div>
- 配置后压缩
html
<div class="text-(center clip 1rem)"></div>
总结一个表格方便查阅
名称 | 作用 | 示例 | 生成结果 |
---|---|---|---|
[] |
生成时直接使用[] 内内容 |
c-[hsla(160,100%,37%,1)] |
color: hsla(160,100%,37%,1) |
$ |
常用在css变量前 | c-$color-text |
color: var(--color-text) |
lg xl 等 |
屏幕适配 | lg="flex place-items-center" |
@media (min-width: 1024px) { display: flex;... } |
quoted: |
常用来表示字符串 | before-content-[quoted:123] | ...::before{ content: "123" } |
_ |
常用来替换空格使用 | grid-cols-[1fr1fr] |
grid-template-columns: 1fr 1fr; |
prefix |
用来解决属性冲突 | ||
transformerDirectives | 在style中复用 | --at-apply: green |
复用green |
transformerVariantGroup | 分组压缩 | class="text-center text-clip text-1rem" |
class="text-(center clip 1rem)" |
嵌套问题
嵌套可以参考pull 568、issues 1748、windicss child-selectors ,根据自己的尝试复杂的嵌套限制比较多,在不深入未深入了解其中原理时,很多规则是无法推断出来的。例如:

但将class
替换为class="children-[a]-(inline-block px-1rem py-0 b-l-(1 solid $color-border))"
时全部失效。通过尝试发现,嵌套的规则较多,而且部分嵌套内容较多,直接编写与标签内不太方便。
对于简单的嵌套可以根据文档编写标签内样式,对于复杂的,可以通过自定义rules
、shortcuts
,或使用transformerDirectives
的方式复用样式,例如
css
<style scoped>
nav a.router-link-exact-active {
--at-apply: c-$color-text;
}
...
nav a:first-of-type {
--at-apply: b-0;
}
</style>