INFO
什么是原子化CSS,UnoCSS又是什么,对此有疑问的推荐看下antfu的这篇文章——重新构想原子化 CSS (antfu.me),相信看完这篇文章的你也会跟我一样热衷于UnoCSS。
准备
首先,使用 vite 创建一个最基础的vue模板
pnpm create vite
安装依赖 unocss,@unocss/reset
pnpm i unocss,@unocss/reset
如果需要使用 UnoCSS 的图标预设,还需要安装@iconify/json
pnpm i @iconify/json
如果需要使用 UnoCSS 的深色模式,最好再安装一下@vueuse/core,方便切换深色模式
pnpm i @vueuse/core
集成 UnoCSS
1. 修改vite.config.js
,添加 unocss plugin
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import unocss from 'unocss/vite'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), unocss()]
})
2. 修改 main.js
和 style.css
main.js
import { createApp } from 'vue'
/** 重置样式 这里引入自定义的重置样式也可 */
import '@unocss/reset/tailwind.css'
/**
* 项目内的样式,
* 注意:最好放在重置样式后,uno.css前
*/
import './style.css'
/** 引入uno.css,不引入不生效 */
import 'uno.css'
import App from './App.vue'
createApp(App).mount('#app')
style.css
:root {
--primary-color: #316c72;
--dark-bg: #18181c;
}
html {
font-size: 4px; // * 方便unocss计算:1单位 = 0.25rem = 1px
}
body {
font-size: 16px;
}
html,
body,
#app {
height: 100%;
margin: 0;
padding: 0;
}
html.dark {
background: var(--dark-bg);
}
注意:
不管是UnoCSS还是tailwindcss、windicss,默认 4单位 = 1rem,即 1单位 = 1/4rem,而 rem 是相对于html的 font-size 来计算的,一般来说大部分浏览器的html默认 font-size 为 16px,即 1rem = 16px,也就是说 Unocss 的1单位换算成 px 就是 4px,这种方式没什么问题,但对于习惯了使用px计算的人来说,每次都要心算一遍要写多少单位就略显麻烦了。那么有没有办法让 unocss 的 1单位=1px
了,这样就没有心算成本了,答案是当然有:由公式 1单位 = 0.25 * ${html font-size} = 1px
可知:将 html 的 font-size 应该为 4px 即可
3. 新增 unocss.config.js
import { defineConfig, presetAttributify, presetUno, presetIcons } from 'unocss'
export default defineConfig({
presets: [presetUno(), presetAttributify(), presetIcons({scale: 1.2, warn: true})],
shortcuts: [
['wh-full', 'w-full h-full'],
['f-c-c', 'flex justify-center items-center'],
['flex-col', 'flex flex-col'],
['text-ellipsis', 'truncate'],
['icon-btn', 'text-16 inline-block cursor-pointer select-none opacity-75 transition duration-200 ease-in-out hover:opacity-100 hover:text-primary !outline-none']
],
rules: [
[/^bc-(.+)$/, ([, color]) => ({ 'border-color': `#${color}` })],
['card-shadow', { 'box-shadow': '0 1px 2px -2px #00000029, 0 3px 6px #0000001f, 0 5px 12px 4px #00000017' }],
],
theme: {
colors: {
primary: 'var(--primary-color)',
dark_bg: 'var(--dark-bg)',
},
},
})
使用UnoCSS
为方便演示怎么使用 unocss ,我准备了一个简单的页面,涉及到 unocss 的 shortcuts (快捷方式) 、图标、深色模式、自定义 rules、自定义 colors, 默认使用属性的方式写,如果想用 class 的方式写直接外面包一层 class 就行
修改 App.vue
<script setup>
import { useDark, useToggle } from '@vueuse/core';
const isDark = useDark()
const toggleDark = useToggle(isDark)
</script>
<template>
<main px-16 py-40 text-center>
<i i-logos-unocss text-48 inline-block />
<p mt-15 text-20 font-bold color-gray-400>UnoCSS</p>
<p text-16 mt-15 inline-flex gap-10>
<i @click="toggleDark()" icon-btn dark:i-carbon-moon i-carbon-sun />
<a
icon-btn i-carbon-logo-github
href="https://github.com/zclzone"
target="_blank"
title="GitHub"
/>
</p>
<section mt-20 w-360 mx-auto flex flex-wrap justify-around p-10 card-shadow rounded-10 dark:b >
<div w-50 h-50 b-1 rounded-5 f-c-c p-10 m-20>
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
</div>
<div w-50 h-50 b-1 rounded-5 flex justify-between p-10 m-20>
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
<span w-6 h-6 rounded-3 self-end bg-black dark:bg-white />
</div>
<div w-50 h-50 b-1 rounded-5 flex justify-between p-10 m-20>
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
<span w-6 h-6 rounded-3 self-center bg-black dark:bg-white />
<span w-6 h-6 rounded-3 self-end bg-black dark:bg-white />
</div>
<div w-50 h-50 b-1 rounded-5 flex justify-between p-10 m-20>
<div flex-col justify-between>
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
</div>
<div flex-col justify-between>
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
</div>
</div>
<div w-50 h-50 b-1 rounded-5 flex-col justify-between items-center p-10 m-20>
<div flex w-full justify-between>
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
</div>
<div w-6 h-6 rounded-3 bg-black dark:bg-white />
<div flex w-full justify-between>
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
</div>
</div>
<div w-50 h-50 b-1 rounded-5 flex-col justify-between p-10 m-20>
<div flex w-full justify-between>
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
</div>
<div flex w-full justify-between>
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
</div>
<div flex w-full justify-between>
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
<span w-6 h-6 rounded-3 bg-black dark:bg-white />
</div>
</div>
</section>
<p mt-20 text-14 color-gray-400>Flex骰子</p>
</main>
</template>
修改 index.html
中的 body,添加如下属性
<body dark:text-white dark:bg-hex-121212>
...
</body>
效果如下图:
插件推荐
UnoCSS 提供了 VsCode 插件,为使用者提供了极大的便利
- UnoCSS
此插件非常强大,不仅有输入提示,并且还可以鼠标悬浮显示编译后的css样式,对自定义的 shortcuts、rules 和 colors 都生效哦, 效果如下图
- Iconify IntelliSense
这个插件并不是特地用于 UnoCSS 的 Icon, 而是因为 UnoCSS 刚好也是使用的 Iconify 图标,作用就是可以预览图标,效果如下图
总结
UnoCSS 绝对是我用过的最好用的原子化CSS了,没有之一,它设计很优雅, 足够轻,用着非常爽,并且它对 tailwindcss 和 windicss 的写法做了兼容,你甚至可以直接对着 tailwindcss 文档写 UnoCSS,过渡成本无限接近 0。
可能你刚开始写原子化CSS的时候会有点痛苦,但请相信我,写熟了之后你一定会直呼:卧槽,真香!
不推荐原生CSS还没写明白的同学直接上手原子化CSS,原生不会写,用原子化CSS只会写得更懵
最后,我将此篇文章对照的源码开源到 github 和 gitee,以便了解和学习的同学对齐和参考
更多 UnoCSS 的用法请参考 unocss/unocss: 官方仓库 (github.com) ,或者查看我的开源项目 Vue Naive Admin ,它基于 Vue3 + Vite + Pinia + UnoCSS + Naive UI,是一个轻量级后台管理模板, 里面有更多 UnoCSS 的实战技巧。