大家好,我是 前端架构师 - 大卫。
更多优质内容请关注微信公众号 @前端大卫。
初心为助前端人🚀,进阶路上共星辰✨,
您的点赞👍与关注❤️,是我笔耕不辍的灯💡。
背景
今天,我们来聊聊 Unocss,这是一款高性能的原子化 CSS 引擎。通过它,你可以在开发中写出更简洁、更高效的 CSS 代码。
接下来,我将结合自己线上项目的实战经验,举一些具体例子,帮助你更直观地理解 Unocss 的强大功能。
Demo 地址:codesandbox.io/p/devbox/lt…
完整源码在文末获取 👇
直观体验:Unocss 的魔力
看看下面这两张图,感受一下使用 Unocss 编写 CSS 的魔法。
什么是 Unocss?
Unocss 是高性能原子化 CSS 引擎,通过以下特性彻底改变你的 CSS 开发体验:
- 🚀 按需生成:只用到的样式才会打包
- 🎨 智能提示:IDE 自动补全类名
- 🧩 灵活扩展:轻松创建自定义规则
- 📱 响应式支持:内置媒体查询方案
实现需求
假设你有一个 1920 x 1080 的页面,HTML 如下:
html体验AI代码助手代码解读复制代码<div class="w-400 h-400 b-10_solid_red text-50 flex-center">Hello World</div>
你希望最终输出的样式如下,那么如何实现这个需求呢?
css体验AI代码助手代码解读复制代码width: 400px; height: 400px; border: 10px solid red; font-size: 50px; display: flex; align-items: center; justify-content: center;
Unocss 集成到 Vite 项目
1. 初始化 Vue 项目
首先,创建一个新的 Vue 项目:
bash体验AI代码助手代码解读复制代码pnpm create vite use-unocss --template vue-ts
2. 安装依赖包
安装 Unocss 以及其他可以帮助你进行单位转换的插件:
bash体验AI代码助手代码解读复制代码pnpm i unocss @unocss/preset-rem-to-px postcss-pxtorem @types/postcss-pxtorem -D
我们使用
@unocss/preset-rem-to-px来将rem转换为px,同时用postcss-pxtorem让px转换为rem,方便你更灵活地编写样式。最终,像w-100这样的类名会自动转换为{ width: 100px }。
3. 配置 Vite
打开 vite.config.ts,并添加 UnoCSS 插件:
ts体验AI代码助手代码解读复制代码import { defineConfig } from "vite"; import vue from "@vitejs/plugin-vue"; import UnoCSS from "unocss/vite"; export default defineConfig({ plugins: [vue(), UnoCSS()], });
4. 导入uno.css 和 配置页面自适应
在 main.ts 中,添加以下代码,使页面能根据窗口大小自动调整字体大小,并导入 uno.css。
ts体验AI代码助手代码解读复制代码import { createApp } from "vue"; import "./style.css"; import App from "./App.vue"; import "uno.css"; // 导入 uno.css const setRemUnit = () => { const docEl = document.documentElement; const pageWidth = docEl.clientWidth; docEl.style.fontSize = pageWidth / 10 + "px"; }; setRemUnit(); window.addEventListener("resize", setRemUnit); createApp(App).mount("#app");
5. 配置 Unocss
创建一个 uno.config.ts 文件,配置一些基础选项,具体每项的详细配置将在后面介绍。
js体验AI代码助手代码解读复制代码import { defineConfig } from ''unocss'' export default defineConfig({ variants: [], shortcuts: {}, rules: [], presets: [], transformers: [] });
6. 配置 PostCSS
最后,创建一个 postcss.config.js 文件,配置 px 转 rem:
js体验AI代码助手代码解读复制代码export default { plugins: { "postcss-pxtorem": { rootValue: 192, // 假设设计稿宽度为 1920px propList: ["*"], minPixelValue: 2, // 忽略小于 2px 的转换 }, }, };
Unocss 配置详解
1. variants
variants 用于配置样式的变体,对在不同分辨率的自适应布局非常有用!
例如,以下配置定义了一个媒体查询,只有在宽高比为 24/9 时才会生效。如果我们使用 5k:w-200,它仅会在宽高比为 24/9 时,将元素的宽度设置为 200px。
js体验AI代码助手代码解读复制代码{ variants: [ (matcher) => { if (matcher.startsWith("5k:")) { return { matcher: matcher.slice(3), parent: "@media (aspect-ratio: 24/9)", }; } }, ], }
2. shortcuts
shortcuts 用于定义常用的样式组合。例如,定义一个 flex-center,它包含了 flex、justify-center 和 items-center,而这些类名又因 Unocss 的预设分别代表不同的含义,如下:
flex代表display: flex。justify-center代表justify-content: center。items-center代表align-items: center。
这些组合可以显著的提高开发效率:
js体验AI代码助手代码解读复制代码{ shortcuts: { "flex-center": "flex justify-center items-center", "flex-x-center": "flex justify-center", "flex-y-center": "flex items-center", "flex-x-between": "flex items-center justify-between", "flex-x-end": "flex items-center justify-end", "wh-full": "w-full h-full", "text-truncate": "whitespace-nowrap overflow-hidden text-ellipsis", "bg-no-repeat-contain": "bg-no-repeat bg-contain", "bg-no-repeat-cover": "bg-no-repeat bg-cover", "abs-full": "absolute left-0 right-0 top-0 bottom-0", "abs-x-center": "absolute left-50% top-0 translate-x--1/2", "abs-y-center": "absolute left-0 top-50% translate-y--1/2", "abs-center": "absolute left-50% top-50% translate-x--1/2 translate-y--1/2", }, }
3. presets
presets 是 Unocss 的一种配置机制,提供了一些常用的预设配置。
-
presetRemToPx({ baseFontSize: 4 }): 这个预设将所有的rem单位转换为px,并使用基础字体大小(baseFontSize)进行转换。例如,baseFontSize为4时,1rem转换为4px,2rem转换为8px。 -
presetUno(): 默认预设,提供了常用工具类(如背景色、间距、排版等),并动态生成 CSS。
js体验AI代码助手代码解读复制代码import { defineConfig, presetUno } from "unocss"; import presetRemToPx from "@unocss/preset-rem-to-px"; export default defineConfig({ presets: [ presetRemToPx({ baseFontSize: 4 }), presetUno(), ], })
4. transformers
transformers 用于扩展和转换输入的类名。
-
transformerDirectives(): 处理指令类(如@apply、@screen、@variants),并将其转化为实际的 CSS 规则或媒体查询。 -
transformerVariantGroup(): 处理变体类的组合(如hover:bg-red-500、focus:text-white),并将它们合并为一组 CSS 声明,使类名更加简洁。
js体验AI代码助手代码解读复制代码import { defineConfig, transformerDirectives, transformerVariantGroup } from "unocss"; import presetRemToPx from "@unocss/preset-rem-to-px"; export default defineConfig({ transformers: [transformerDirectives(), transformerVariantGroup()], })
5. rules
rules 用于定义自定义的 CSS 规则,并支持正则匹配。通过这些规则,你可以创建简洁而强大的 CSS 语法,提高开发效率:
1. transform 相关
transform-1-linear相当于{ transition: transform 1s linear; }transform-2-bounce相当于{ transition: transform 2s bounce; }
js体验AI代码助手代码解读复制代码[ /^transform-(\d+)-(.+)$/, ([, duration, timingFunction]) => ({ transition: `transform ${duration}s ${timingFunction}`, }), ]
2. width 和 height 联合简写
wh-10相当于{ width: 10px; height: 10px; }
js体验AI代码助手代码解读复制代码[ /^wh-(\d+)$/, ([, wh]) => ({ width: `${wh}px`, height: `${wh}px`, }), ]
3. absolute 相关简写
absolute-l-10相当于{ position: absolute; left: 10px; }absolute-lr-10相当于{ position: absolute; left: 10px; right: 10px; }
js体验AI代码助手代码解读复制代码[ /^absolute-([lrtb]{1,4})-(\d+)$/, ([, directions, dis]) => { const styles = { position: "absolute", }; const obj = { l: "left", r: "right", t: "top", b: "bottom", }; for (const key in obj) { if (directions.includes(key)) { styles[obj[key]] = dis + "px"; } } return styles; }, ]
4. background-color 相关
bg-rgba(255,255,0,0.2)相当于{ background-color: rgba(255,255,0,0.2); }
js体验AI代码助手代码解读复制代码[ /^bg-rgba\((\d+),(\d+),(\d+),([0,1]?\.?\d*)\)$/, ([, r, g, b, a]) => ({ "background-color": `rgba(${r},${g},${b},${a})`, }), ]
5. border 相关
b-1_solid_blue相当于{ border: 1px solid blue; }bt-1_solid_red相当于{ border-top: 1px solid red; }br-1_dashed_rgba(255,0,0,0.5)相当于{ border-right: 1px dashed rgba(255,0,0,0.5); }
注意:目前 VSCode 插件 Unocss 不支持预览带有
rgba的写法。
js体验AI代码助手代码解读复制代码[ /^(b|outline)(t|r|b|l)?-(\d+)_(solid|dashed|dotted)_(#[0-9a-fA-F]{3,6}|rgba\((\d+),(\d+),(\d+),([0,1]?\.?\d*)\)|\w+)$/, ([, type, dir = "", width, style, color]) => { const bType = { b: "border", outline: "outline", }; const dirObj = { t: "-top", r: "-right", b: "-bottom", l: "-left", "": "", }; return { [`${bType[type]}${dirObj[dir]}`]: `${width}px ${style} ${color}`, }; }, ]
6. background 相关
bg[url]相当于{ background: url(xxx) no-repeat left top / contain; }bg-cover[url]相当于{ background: url(xxx) no-repeat left top / cover; }bg-center_top[url]相当于{ background: url(xxx) no-repeat center top / cover; }bg-left_center-100%_120%[url]相当于{ background: url(xxx) no-repeat left center / 100% 120%; }
js体验AI代码助手代码解读复制代码[ /^bg(?:-([a-z]+-[a-z]+|repeat))?(?:-(\d+%?_\d+%?|[a-z]+_[a-z]+))?(?:-(\d+%?_\d+%?|[a-z]+))?\[(.*)\]$/, ([, repeat = "no-repeat", pos = "left_top", size = "contain", url]) => { return { background: `url(${url}) ${repeat} ${pos.replace( "_", " " )} / ${size.replace("_", " ")}`, }; }, ]
7. padding 和 margin
p-1相当于{ padding: 1px; }p-1_2相当于{ padding: 1px 2px; }p-1_2_3相当于{ padding: 1px 2px 3px; }p-1_2_3_4相当于{ padding: 1px 2px 3px 4px; }m-1相当于{ margin: 1px; }m-1_2相当于{ margin: 1px 2px; }m-1_2_3相当于{ margin: 1px 2px 3px; }m-1_2_3_4相当于{ margin: 1px 2px 3px 4px; }
js体验AI代码助手代码解读复制代码[ /^([pm])-(\d+)(?:_(\d+))(?:_(\d+))?(?:_(\d+))?(?:_(\d+))?$/, ([, type, top, right, bottom, left]) => { const pm = type === "p" ? "padding" : "margin"; const sides = [top, right, bottom, left] .filter(Boolean) .map((item) => item + "px") .join(" "); return { [pm]: sides, }; }, ]
总结
通过本文的配置方案,你可以:
✅ 减少 70% 的 CSS 代码量
✅ 提升 3 倍样式开发速度
✅ 轻松实现响应式布局
✅ 告别 class 命名焦虑
Tips:建议配合 VSCode 的Unocss 插件使用,获得代码提示和实时预览功能。
Unocss 插件地址:
完整源码地址:
如果本文对你有帮助,欢迎点赞❤️收藏⭐,也欢迎在评论区交流您的 Unocss 使用心得!