Skip to content
On this page

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.jsstyle.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>

效果如下图:

image.png

image.png

插件推荐

UnoCSS 提供了 VsCode 插件,为使用者提供了极大的便利

  1. UnoCSS

此插件非常强大,不仅有输入提示,并且还可以鼠标悬浮显示编译后的css样式,对自定义的 shortcuts、rules 和 colors 都生效哦, 效果如下图

image.png

  1. Iconify IntelliSense

这个插件并不是特地用于 UnoCSS 的 Icon, 而是因为 UnoCSS 刚好也是使用的 Iconify 图标,作用就是可以预览图标,效果如下图

image.png

总结

UnoCSS 绝对是我用过的最好用的原子化CSS了,没有之一,它设计很优雅, 足够轻,用着非常爽,并且它对 tailwindcss 和 windicss 的写法做了兼容,你甚至可以直接对着 tailwindcss 文档写 UnoCSS,过渡成本无限接近 0。

可能你刚开始写原子化CSS的时候会有点痛苦,但请相信我,写熟了之后你一定会直呼:卧槽,真香!

不推荐原生CSS还没写明白的同学直接上手原子化CSS,原生不会写,用原子化CSS只会写得更懵


最后,我将此篇文章对照的源码开源到 github 和 gitee,以便了解和学习的同学对齐和参考

gitee:unocss-demo

github:unocss-demo

更多 UnoCSS 的用法请参考 unocss/unocss: 官方仓库 (github.com) ,或者查看我的开源项目 Vue Naive Admin ,它基于 Vue3 + Vite + Pinia + UnoCSS + Naive UI,是一个轻量级后台管理模板, 里面有更多 UnoCSS 的实战技巧。