前言
在原子化 CSS 的世界里,Tailwind CSS 已经成为了事实标准。然而,随着项目规模的扩大和开发体验需求的提升,Tailwind 在灵活性、扩展性和按需生成能力上的局限逐渐显现。UnoCSS 作为一颗冉冉升起的新星,以其"引擎而非框架"的核心理念,为我们提供了一种全新的原子化 CSS 解决方案。
UnoCSS 是由 Anthony Fu 开发的即时按需原子化 CSS 引擎。它的核心理念是:不预设任何样式,只提供引擎。 所有的样式规则通过预设(presets)和规则(rules)动态生成,让开发者拥有完全的控制权。
一、UnoCSS 的核心架构
| 层级 | 说明 | 对应概念 |
|---|---|---|
| 引擎层 | 负责匹配规则、生成 CSS、处理 HMR | UnoCSS core |
| 规则层 | 定义从类名到 CSS 的映射关系 | rules / shortcuts |
| 预设层 | 一组规则、变体、快捷方式的集合 | presets |
引擎本身不包含任何 CSS 规则,所有功能都通过预设加载。这意味着你可以完全定制属于你的原子化 CSS 体系。
二、规则系统详解
2.1 静态规则
rules: [
['m-0', { margin: '0px' }],
['m-1', { margin: '0.25rem' }],
['text-center', { 'text-align': 'center' }],
]
2.2 动态规则
rules: [
// 间距规则: m-4, m-8, m-12...
[/^m-(\d+)$/, ([, num]) => ({ margin: `${num * 0.25}rem` })],
// 方向间距: mt-4, mr-2, mb-8...
[/^([mtp])-(\d+)$/, ([, dir, num]) => {
const dirs = { m: 'margin', t: 'margin-top', p: 'padding' }
return { [dirs[dir]]: `${num * 0.25}rem` }
}],
// 任意值: w-[100px], h-[50vh]
[/^w-\[(.+)\]$/, ([, val]) => ({ width: val })],
[/^h-\[(.+)\]$/, ([, val]) => ({ height: val })],
// 颜色: text-red-500, bg-blue-400
[/^text-(\w+)-(\d+)$/, ([, color, shade]) => ({
color: `var(--${color}-${shade})`,
})],
]
2.3 规则的完整签名
rules: [
[
/^grid-cols-(\d+)$/,
([, num], { theme }) => ({
'grid-template-columns': `repeat(${num}, minmax(0, 1fr))`,
}),
{ layer: 'utilities', autocomplete: 'grid-cols-(1-12)' },
],
]
2.4 规则的匹配顺序
规则匹配是有序的——从上到下,第一个匹配到的规则胜出。最佳实践:将更具体的规则放在前面,更通用的动态规则放在后面。
三、变体系统
3.1 内置变体
<div class="hover:text-blue-500 active:text-red-500"></div>
<div class="md:text-lg lg:text-xl"></div>
<div class="dark:bg-gray-800"></div>
<div class="md:hover:text-blue-500 dark:hover:bg-gray-700"></div>
3.2 自定义变体
variants: [
// 自定义 RTL 变体
(matcher) => {
if (!matcher.startsWith('rtl:')) return matcher
return { matcher: matcher.slice(4), selector: s => `[dir="rtl"] ${s}` }
},
// 自定义打印变体
(matcher) => {
if (!matcher.startsWith('print:')) return matcher
return { matcher: matcher.slice(6), selector: s => `@media print { ${s} }` }
},
]
四、预设生态系统
4.1 presetWind(Tailwind 兼容)
import { defineConfig, presetWind } from 'unocss'
export default defineConfig({ presets: [presetWind()] })
4.2 presetAttributify(属性化模式)
<!-- 属性化方式 -->
<button bg="blue-500 hover:blue-600" text="white" p="x-4 y-2" rounded="lg">按钮</button>
4.3 presetIcons(图标预设)
<i class="i-mdi-home text-2xl"></i>
<i class="i-logos-vue text-3xl"></i>
<i class="i-carbon-sun dark:i-carbon-moon"></i>
UnoCSS 会在构建时按需下载图标集并内联为 SVG data URL,零运行时开销。
4.4 presetTypography(排版预设)
<article class="prose prose-lg dark:prose-invert">
<h1>文章标题</h1>
<p>这是一段正文内容...</p>
</article>
五、Shortcuts(快捷方式)
shortcuts: [
// 静态快捷方式
{
'btn': 'px-4 py-2 rounded-lg font-medium transition-colors',
'btn-primary': 'btn bg-blue-500 text-white hover:bg-blue-600',
'card': 'bg-white dark:bg-gray-800 rounded-lg shadow-md p-6',
},
// 动态快捷方式
[/^btn-(\w+)$/, ([, color]) => `btn bg-${color}-500 text-white hover:bg-${color}-600`],
]
六、与 Tailwind CSS 的核心差异
| 特性 | Tailwind CSS | UnoCSS |
|---|---|---|
| 生成方式 | 预定义扫描 + JIT | 按需动态生成 |
| 扩展性 | 配置文件覆盖 | 规则引擎完全开放 |
| 包体积 | ~10KB | 引擎 ~6KB + 按需 |
| 自定义规则 | 仅通过 theme.extend | 正则 + 函数,任意自定义 |
| 变体系统 | 固定集合 | 任意自定义变体函数 |
| 属性化模式 | 需要 plugin | 内置预设 |
| 图标支持 | 需单独方案 | 内置 presetIcons |
| 引擎速度 | 很快 | 极快 |
| 模式 | 框架 | 引擎 |
核心差异在于理念不同:Tailwind 是一个框架,预设了一套完整的样式系统;而 UnoCSS 是一个引擎,只负责匹配和生成。
七、在 Vite / Nuxt 中配置
// vite.config.ts
import UnoCSS from 'unocss/vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({ plugins: [UnoCSS(), vue()] })
// uno.config.ts
import { defineConfig, presetWind, presetAttributify, presetIcons, transformerDirectives, transformerVariantGroup } from 'unocss'
export default defineConfig({
presets: [presetWind(), presetAttributify(), presetIcons({ scale: 1.2 })],
transformers: [transformerDirectives(), transformerVariantGroup()],
shortcuts: {
'btn': 'px-4 py-2 rounded-lg font-medium transition-colors cursor-pointer',
'btn-primary': 'btn bg-blue-500 text-white hover:bg-blue-600',
},
})
八、Transformers(转换器)
transformerDirectives
.btn { @apply px-4 py-2 rounded-lg bg-blue-500 text-white; @apply hover:bg-blue-600 transition-colors; }
transformerVariantGroup
<!-- 分组写法 -->
<div class="hover:(bg-blue-500 text-white border-blue-300)"></div>
<div class="md:(flex items-center justify-between)"></div>
九、性能优化与最佳实践
| 实践 | 建议 |
|---|---|
| 预设选择 | 优先用 presetWind + presetAttributify |
| 规则优先级 | 具体 → 通用,从上到下 |
| Shortcuts | 抽取高频组合,保持 DRY |
| Safelist | 动态拼接的类名需要加入 safelist |
| Blocklist | 阻止不需要的规则生成 |
| 图标按需 | 使用 presetIcons 而非图标字体 |
| Variant Groups | 开启 transformerVariantGroup 减少重复 |
| CSS Layers | 利用 layers 控制优先级 |
十、完整生产级配置
import { defineConfig, presetWind, presetAttributify, presetIcons, presetTypography, presetWebFonts, transformerDirectives, transformerVariantGroup, presetContainerQueries } from 'unocss'
export default defineConfig({
presets: [
presetWind(),
presetAttributify(),
presetIcons({ scale: 1.2, prefix: 'i-', extraProperties: { display: 'inline-block', 'vertical-align': 'middle' } }),
presetTypography(),
presetWebFonts({ provider: 'google', fonts: { sans: ['Inter:400,600,700'], mono: ['Fira Code:400,600'] } }),
presetContainerQueries(),
],
transformers: [transformerDirectives(), transformerVariantGroup()],
theme: {
colors: { brand: { 50: '#eff6ff', 500: '#3b82f6', 600: '#2563eb', 700: '#1d4ed8' } },
},
shortcuts: {
'btn': 'inline-flex items-center justify-center px-4 py-2 rounded-lg font-medium transition-all duration-200 cursor-pointer',
'btn-primary': 'btn bg-brand-500 text-white hover:bg-brand-600 active:scale-95',
'card': 'bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 p-6',
'input': 'w-full px-3 py-2 rounded-lg border border-gray-300 focus:ring-2 focus:ring-brand-500 outline-none transition-all',
},
rules: [
[/^animate-(\w+)$/, ([, name]) => ({ animation: `${name} 1s ease-in-out infinite` })],
['scrollbar-thin', { 'scrollbar-width': 'thin', 'scrollbar-color': 'rgb(203 213 225) transparent' }],
],
safelist: ['animate-fade-in', 'animate-slide-up'],
})
结语
UnoCSS 的核心理念——引擎而非框架——赋予了前端开发者前所未有的灵活性。通过规则系统、变体系统、预设生态和转换器的组合,你可以构建出完全符合项目需求的原子化 CSS 体系。
相比于 Tailwind,UnoCSS 在扩展性、性能和开发体验上都有显著优势。在实际项目中,建议从 presetWind 起步,逐步引入 presetAttributify、presetIcons 等预设,通过 shortcuts 和自定义规则构建属于自己的设计系统。
Comments | 0条评论