npm package: @limeui/unocss-preset
Description: 让 UnoCSS 支持 uni-app 和 uni-app x，提供平台条件样式等特性
Latest version: 0.0.9

# lime-unocss-preset

UnoCSS preset for uni-app，支持 uni-app 和 uni-app x。

## 特性

- 🎨 支持 uni-app 和 uni-app x 全平台
- 📱 支持小程序、App、H5 等所有 uni-app 平台
- 🔄 支持平台条件样式（如 `uni-weixin:`、`uni-h5:`）
- 🎯 支持排除平台（如 `uni-not-weixin:`）
- 🌓 支持主题系统，包括浅色/深色主题切换
- 🎨 支持自动生成色阶（Tailwind 风格）
- 📝 支持 `@` 符号引用 CSS 变量

## 安装

### 方式一：通过 npm 安装

```bash
npm install unocss @limeui/unocss-preset
# 或
yarn add unocss @limeui/unocss-preset
# 或
pnpm add unocss @limeui/unocss-preset
```

### 方式二：通过 uni-app 插件市场安装

在 uni-app 插件市场中搜索并导入 `lime-unocss-preset`。

```bash
# 同时需要安装 unocss
npm install unocss
```

## 使用

本配置基于 HBuilderX 开发环境。

### 目录结构

配置完成后，项目目录结构如下：

```
your-project/
├── vite.config.ts          # Vite 配置文件
├── uno.config.ts           # UnoCSS 配置文件
├── main.ts / main.uts       # 入口文件
├── pages/                  # 页面目录
│   └── index.uvue
├── App.uvue                # 应用入口组件
└── package.json
```

### Vite 插件配置

在 `vite.config.ts` 中配置 UnoCSS 插件：

```typescript
import { defineConfig } from 'vite'
import Uni from '@dcloudio/vite-plugin-uni'

export default async () => {
	const UnoCSS = (await import('unocss/vite')).default
	
	return defineConfig({
		plugins: [
			Uni(),
			UnoCSS()
		]
	})
}
```

### 引入样式

在 `main.ts` 或 `main.uts` 中引入 UnoCSS 样式：

```typescript
import 'virtual:uno.css'
```

### UnoCSS 配置

在项目根目录创建 `uno.config.ts` 文件：

```typescript
import { defineConfig } from 'unocss'
// 优先使用 npm 包安装
import { presetUnix } from '@limeui/unocss-preset'
// 通过 uni-app 插件市场安装时使用
// import { presetUnix } from './uni_modules/lime-unocss-preset'

export default defineConfig({
	content: {
		pipeline: {
			include: [
				/\.(uvue|vue)($|\?)/ // 包含 .vue 和 .uvue 文件
			],
			exclude: [
				/node_modules/, // 排除 node_modules
				/dist/, // 排除 dist 目录
				/uni_modules/, // 排除 uni_modules
				/components/ // 排除 components 目录
			]
		}
	},
	presets: [
		presetUnix()
	]
})
```

## 配置选项

### uno

- 类型: `boolean | PresetAppletOptions`
- 默认值: `true`

是否启用 `@unocss/preset-uno` 预设。默认启用，传递 `false` 可禁用。也可以传递配置对象来自定义预设选项。

```typescript
presetUnix({
	uno: true // 启用（默认）
})

presetUnix({
	uno: false // 禁用
})

presetUnix({
	uno: {
		dark: 'media' // 通过媒体查询切换深色模式
	}
})

presetUnix({
	uno: {
		dark: 'class' // 通过 .dark 类名切换深色模式
	}
})
```

**dark 模式说明**：
- `dark: 'media'` - 使用 `@media (prefers-color-scheme: dark)` 媒体查询，根据系统主题自动切换
- `dark: 'class'` - 使用 `.dark` 类名，需要手动在父元素上添加 `.dark` 类来启用深色模式

### replaceOpacityVar

- 类型: `boolean`
- 默认值: `true`

是否将 `var(--un-*-opacity)` 替换为具体数值。

```typescript
presetUnix({
	replaceOpacityVar: true // 启用（默认）
})

presetUnix({
	replaceOpacityVar: false // 禁用
})
```

**说明**：启用后，会自动将 `var(--un-text-opacity)`、`var(--un-bg-opacity)` 等变量替换为对应的数值（如 `0.5`），避免在appx平台出现兼容性问题。

### remRpx

- 类型: `boolean | RemRpxOptions`
- 默认值: `{ mode: 'rem2px' }`

配置 rem、rpx 和 px 单位的转换。

```typescript
presetUnix({
	remRpx: { mode: 'rem2px' } // rem 转 px（默认）
})

presetUnix({
	remRpx: { mode: 'rem2px', baseFontSize: 16 } // rem 转 px，指定基准字体大小
})

presetUnix({
	remRpx: { mode: 'rem2rpx' } // rem 转 rpx（小程序平台）
})

presetUnix({
	remRpx: { mode: 'rpx2rem' } // rpx 转 rem（H5 平台）
})

presetUnix({
	remRpx: false // 禁用转换
})
```

**说明**：
- `mode: 'rem2px'` - 将 rem 单位转换为 px（默认模式，适用于所有平台）
  - `baseFontSize` - rem 转换的基准字体大小，默认为 16（即 1rem = 16px）
- `mode: 'rem2rpx'` - 将 rem 单位转换为 rpx（适用于小程序平台）
- `mode: 'rpx2rem'` - 将 rpx 单位转换为 rem（适用于 H5 平台）
- 默认使用 `rem2px` 模式，适合 uni-app x APP 和其他平台


### attributify

- 类型: `boolean | PresetAttributifyOptions & TransformerAttributifyOptions`
- 默认值: `false`

开关/配置属性模式（attributify mode）。小程序平台是否使用 transformerAttributify。

```typescript
presetUnix({
	attributify: true // 启用（默认）
})

presetUnix({
	attributify: false // 禁用
})

presetUnix({
	attributify: {
		ignoreAttributes: ['block', 'fixed'], // 忽略的属性名
		prefixedOnly: true // 只匹配带前缀的属性
	}
})
```

**说明**：
- 属性模式允许使用 HTML 属性语法来应用样式，如 `<view text-red>红色文字</view>`
- `ignoreAttributes` - 忽略的属性名列表，避免与组件原生属性冲突
- `prefixedOnly: true` - 只匹配带前缀的属性（如 `text-red`），避免与原生属性冲突，推荐开启

### classCharReplace

- 类型: `boolean | 'class' | 'global'`
- 默认值: `true`

是否替换类名中的特殊字符。将包含不支持字符的类名转换为支持的字符。

```typescript
presetUnix({
	classCharReplace: true // 启用（默认），精准匹配，只在 class 和 hover-class 中替换
})

presetUnix({
	classCharReplace: false // 禁用
})

presetUnix({
	classCharReplace: 'class' // 精准匹配，只在 class 和 hover-class 中替换
})

presetUnix({
	classCharReplace: 'global' // 全部匹配，全局替换
})
```

**说明**：
- **boolean 模式**：
  - `true` - 启用，自动将包含不支持字符（如 `!`、`@`、`#` 等）的类名转换为支持的字符，精准匹配，只在 class 和 hover-class 中替换
  - `false` - 禁用，类名保持原样
- **字符串模式**：
  - `'class'` - 精准匹配，只在 class 和 hover-class 中替换
  - `'global'` - 全部匹配，全局替换


**注意事项**：
- 此转换器仅在小程序和 APPX 平台生效
- 转换会创建 shortcuts 映射，确保样式正确应用
- 由于涉及类名替换，可能存在一定风险，建议在测试环境充分验证后再在生产环境使用
- `'global'` 模式会在整个代码中全局替换，可能会影响非 class 属性中的内容，请谨慎使用


## 主题系统

本插件提供了 `presetTheme` 预设，用于配置主题系统，包括颜色、浅色/深色主题、自定义变量等。

### 导入

```typescript
// 优先使用 npm 包安装
import { presetTheme } from '@limeui/unocss-preset'
// 通过 uni-app 插件市场安装时使用
// import { presetTheme } from './uni_modules/lime-unocss-preset'
```

### 使用

```typescript
import { defineConfig } from 'unocss'
// 优先使用 npm 包安装
import { presetUnix, presetTheme, isUniappx, isApp } from '@limeui/unocss-preset'
// 通过 uni-app 插件市场安装时使用
// import { presetUnix, presetTheme, isUniappx, isApp } from './uni_modules/lime-unocss-preset'

export default defineConfig({
	presets: [
		presetUnix({
			replaceOpacityVar: true,
			uno: {
				dark: 'class' // uniappx app最好使用class，因为没有媒体查询
			}
		}),
		presetTheme({
			theme: {
				colors: {
					primary: '#3283ff',
					error: '#FF4D4F',
					warning: '#ffb400',
					success: '#34c471',
					info: '#3283ff',
				},
				light: {
					var: {
						'text-color-1': 'rgba(0,0,0,0.88)',
						'text-color-2': 'rgba(0,0,0,0.65)',
						'text-color-3': 'rgba(0,0,0,0.45)',
						'text-color-4': 'rgba(0,0,0,0.25)',
						'bg-color-page': '#f3f3f3',
						'bg-color-container': '#ffffff',
						'bg-color-elevated': '#ffffff',
						'bg-color-spotlight': 'rgba(0, 0, 0, 0.85)',
						'bg-color-mask': 'rgba(0, 0, 0, 0.45)',
					}
				},
				dark: {
					var: {
						'text-color-1': 'rgba(255,255,255,0.85)',
						'text-color-2': 'rgba(255,255,255,0.65)',
						'text-color-3': 'rgba(255,255,255,0.45)',
						'text-color-4': 'rgba(255,255,255,0.25)',
						'bg-color-page': '#181818',
						'bg-color-container': '#242424',
						'bg-color-elevated': '#242424',
						'bg-color-spotlight': '#4b4b4b',
						'bg-color-mask': 'rgba(0, 0, 0, 0.65)',
					}
				}
			},
			selectors: {
				light: isUniappx && isApp ? '.page,.l-portal' : ':root,page,.l-portal',
				dark: '.dark'
			},
			prefix: '--l',
		})
	]
})
```

### 配置选项

#### theme

- 类型: `ThemeOptions`
- 默认值: `undefined`

配置主题系统，包括颜色、浅色/深色主题、自定义变量等。

```typescript
interface ThemeOptions {
	colors?: ThemeColor
	light?: {
		colors?: ThemeColor
		var?: ThemeColor
	}
	dark?: {
		colors?: ThemeColor
		var?: ThemeColor
	}
	selectors?: {
		dark?: string
		light?: string
		[key: string]: string | undefined
	}
	prefix?: string
	darkBackgroundColor?: string
}
```

- **colors**: 主色调，会自动生成 10 个色阶（1-10），支持单个颜色或颜色数组
- **light.colors**: 浅色主题的颜色，会自动生成色阶，支持单个颜色或颜色数组
- **dark.colors**: 深色主题的颜色，会自动生成色阶，支持单个颜色或颜色数组
- **light.var**: 浅色主题的自定义变量，不生成色阶
- **dark.var**: 深色主题的自定义变量，不生成色阶
- **selectors**: 主题选择器配置
  - `light`: 浅色主题选择器，默认为 `:root,page,.l-portal`
  - `dark`: 深色主题选择器，默认为 `.dark`
  - **uni-app x app** 不支持 `:root`，建议设置为 `page,.l-portal`
- **prefix**: CSS 变量前缀，默认为 `--l`，所有生成的 CSS 变量都会加上此前缀
- **darkBackgroundColor**: 深色主题背景色，默认为 `#141414`，用于生成深色色阶时的混合计算

#### 色阶生成

`colors`、`light.colors`、`dark.colors` 中的颜色会自动生成 10 个色阶。

**单个颜色**：会自动生成 10 个色阶，使用 **Ant Design 色阶算法**生成

```typescript
colors: {
	primary: '#3283ff'
}
```

生成：
```css
--l-primary-color-1: #e6f2ff
--l-primary-color-2: #cce5ff
--l-primary-color-3: #99c7ff
--l-primary-color-4: #66a9ff
--l-primary-color-5: #338bff
--l-primary-color: #3283ff
--l-primary-color-7: #2a6fda
--l-primary-color-8: #225bb3
--l-primary-color-9: #1a478c
--l-primary-color-10: #123366
```

**颜色数组**：直接使用数组作为色阶，不使用算法生成

```typescript
colors: {
	success: ['#d4edda', '#c3e6cb', '#b1dfc4', '#a0d7bd', '#8ecfb6', '#7cc8af', '#6ac1a8', '#58baa1', '#46b39a', '#34ac93']
}
```

生成：
```css
--l-success-color-1: #d4edda
--l-success-color-2: #c3e6cb
--l-success-color-3: #b1dfc4
--l-success-color-4: #a0d7bd
--l-success-color-5: #8ecfb6
--l-success-color: #7cc8af
--l-success-color-7: #6ac1a8
--l-success-color-8: #58baa1
--l-success-color-9: #46b39a
--l-success-color-10: #34ac93
```

#### Tailwind 色阶支持
支持使用 Tailwind 风格的色阶（50-900）。当你在 `colors` 中配置了颜色后，会自动生成色阶格式：

```html
<view class="text-primary-500">主色文本</view>
<view class="bg-primary-100">浅色背景</view>
<view class="border-error-600">错误边框</view>
```

#### @ 符号引用
在自定义规则中可以使用 `@` 符号引用 `light.var` 和 `dark.var` 中定义的变量。引用时会自动转换为 CSS 变量格式（`--l-变量名`）：

```typescript
rules: [
	[
		/^text-default$/,
		() => ({ 'color': '@text-color-1' })
	],
	[
		/^bg-page$/,
		() => ({ 'background-color': '@bg-color-page' })
	]
]
```

生成的 CSS：
```css
.text-default {
	color: var(--l-text-color-1, rgba(0,0,0,0.88));
}

.bg-page {
	background-color: var(--l-bg-color-page, #f3f3f3);
}
```

#### 主题切换

支持通过类名或媒体查询切换主题：

```typescript
// 通过类名切换
selectors: {
	light: '.light',
	dark: '.dark'
}

// 使用
<text class="light">浅色主题</text>
<text class="dark">深色主题</text>
```

```typescript
// 通过媒体查询切换（默认）
selectors: {
	// 不设置，使用默认的媒体查询
}
```



## 平台条件样式

### 包含平台

```html
<!-- 只在微信小程序生效 -->
<view class="uni-weixin:text-red">微信小程序红色文字</view>

<!-- 只在 H5 生效 -->
<view class="uni-h5:bg-blue">H5 蓝色背景</view>

<!-- 只在 AppX 生效 -->
<view class="uni-appx:p-4">AppX 内边距</view>
```

### 排除平台

```html
<!-- 在除微信小程序外的所有平台生效 -->
<view class="uni-not-weixin:text-red">非微信小程序红色文字</view>

<!-- 在除 H5 外的所有平台生效 -->
<view class="uni-not-h5:bg-blue">非 H5 蓝色背景</view>
```

### 属性模式

配合 attributify 模式，可以使用属性语法：

```html
<!-- 只在微信小程序生效 -->
<view uni-weixin:text-red>微信小程序红色文字</view>

<!-- 只在 H5 生效 -->
<view uni-h5:bg-blue>H5 蓝色背景</view>
```

### 支持的平台

- 小程序：`mp-weixin`（微信）、`mp-alipay`（支付宝）、`mp-baidu`（百度）、`mp-qq`（QQ）、`mp-toutiao`（头条）、`mp-kuaishou`（快手）、`mp-lark`（飞书）、`mp-jd`（京东）、`mp-360`（360）
- App：`app`、`app-plus`、`app-harmony`（鸿蒙）、`app-android`、`app-ios`
- uni-app x APP：`appx`（安卓、iOS、鸿蒙）
- H5/Web：`h5`、`web`（两者互通）
- 快应用：`quickapp`、`quickapp-webview` 等

### 简写形式

```html
<!-- 使用简写（去掉 mp- 前缀） -->
<view class="uni-weixin:text-sm">微信小程序小字体</view>
<view class="uni-alipay:text-sm">支付宝小程序小字体</view>
<view class="uni-baidu:text-sm">百度小程序小字体</view>
<view class="uni-qq:text-sm">QQ小程序小字体</view>
<view class="uni-toutiao:text-sm">头条小程序小字体</view>
<view class="uni-kuaishou:text-sm">快手小程序小字体</view>
<view class="uni-lark:text-sm">飞书小程序小字体</view>
<view class="uni-jd:text-sm">京东小程序小字体</view>
```

### 平台别名

| 别名 | 实际平台 |
|------|----------|
| `weixin` | `mp-weixin` |
| `alipay` | `mp-alipay` |
| `baidu` | `mp-baidu` |
| `qq` | `mp-qq` |
| `toutiao` | `mp-toutiao` |
| `kuaishou` | `mp-kuaishou` |
| `lark` | `mp-lark` |
| `jd` | `mp-jd` |
| `h5` / `web` | `h5`（两者互通） |



## uni-app x APP 限制

uni-app x APP（`.uvue` 文件）的 CSS 选择器支持有限制，**只支持类名选择器**，不支持复杂的组合选择器。

### 不支持的类名

以下类名在 uni-app x APP 中**不支持**：

#### Space 相关类名
`space-x-*` 和 `space-y-*` 系列类名会生成包含子选择器（`>`）和相邻兄弟选择器（`+`）的 CSS 规则，因此不支持：

```html
<!-- 不支持 -->
<view class="space-x-4">
  <view>项目1</view>
  <view>项目2</view>
</view>

<view class="space-y-4">
  <view>项目1</view>
  <view>项目2</view>
</view>
```

生成的 CSS（不支持）：
```css
.space-x-4 > * + * {
  margin-left: 1rem;
}

.space-y-4 > * + * {
  margin-top: 1rem;
}
```

**替代方案**：使用 margin 属性

手动为子元素添加 margin：

```html
<!-- 水平间距 -->
<view class="flex">
  <view class="mr-4">项目1</view>
  <view class="mr-4">项目2</view>
  <view>项目3</view>
</view>

<!-- 垂直间距 -->
<view class="flex flex-col">
  <view class="mb-4">项目1</view>
  <view class="mb-4">项目2</view>
  <view>项目3</view>
</view>
```

#### 其他复杂选择器

任何会生成复杂选择器的类名都不支持，包括但不限于：
- 使用 `>`（子选择器）的类名
- 使用 `+`（相邻兄弟选择器）的类名
- 使用 `~`（通用兄弟选择器）的类名
- 使用 `:has()` 等伪类选择器的类名
- 使用 `:focus` 伪类选择器的类名
- 使用 `:active` 伪类选择器的类名
- 使用 `:disabled` 伪类选择器的类名
- 使用 `:first-child` 伪类选择器的类名
- 使用 `:last-child` 伪类选择器的类名
- 使用 `:hover` 伪类选择器的类名（uni-app 使用 `hover-class` 属性替代）
- 使用 `:visited` 伪类选择器的类名
- 使用 `:link` 伪类选择器的类名
- 使用 `:checked` 伪类选择器的类名
- 使用 `:empty` 伪类选择器的类名
- 使用 `:nth-child()` 伪类选择器的类名
- 使用 `:nth-of-type()` 伪类选择器的类名
- 使用 `:not()` 伪类选择器的类名
- 使用 `:before`、`::before` 伪元素的类名
- 使用 `:after`、`::after` 伪元素的类名

#### 不支持的 CSS 属性

以下 CSS 属性在 uni-app x APP 中也不支持：
- `gap` 属性（包括 `row-gap`、`column-gap`）
- `grid` 相关属性（包括 `grid-template-columns`、`grid-template-rows`、`grid-gap` 等）
- `aspect-ratio` 属性
- `cursor` 属性
- `user-select` 属性（包括 `-webkit-user-select`）
- `overflow-wrap` 属性
- `text-transform` 属性
- `outline-width` 属性
- `outline-color` 属性
- `outline-style` 属性
- `outline-offset` 属性

#### 不支持的 CSS 属性值

以下 CSS 属性值在 uni-app x APP 中不支持：

**flex-direction 属性**：只支持 `row`、`column`
- ❌ `flex-direction: row-reverse`
- ❌ `flex-direction: column-reverse`
- ✅ `flex-direction: row`
- ✅ `flex-direction: column`

**display 属性**：只支持 `flex` 和 `none`
- ❌ `display: block`
- ❌ `display: inline-block`
- ✅ `display: flex`
- ✅ `display: none`

**overflow 属性**：只支持 `visible` 和 `hidden`
- ❌ `overflow: auto`
- ❌ `overflow: scroll`
- ✅ `overflow: visible`
- ✅ `overflow: hidden`

**font-weight 属性**：只支持 `normal`、`bold`、`400`、`500`、`600`、`700`
- ❌ `font-weight: 100` (thin)
- ❌ `font-weight: 200` (extralight)
- ❌ `font-weight: 300` (light)
- ✅ `font-weight: 400` (normal)
- ✅ `font-weight: 500` (medium)
- ✅ `font-weight: 600` (semibold)
- ✅ `font-weight: 700` (bold)
- ❌ `font-weight: 800` (extrabold)
- ❌ `font-weight: 900` (black)

#### 不支持的类名

**display 相关类名**：
```html
<!-- 不支持 -->
<view class="block">块级元素</view>
<view class="inline-block">行内块元素</view>

<!-- 替代方案 -->
<view class="flex">使用 flex 布局</view>
<view class="hidden">隐藏元素</view>
```

**overflow 相关类名**：
```html
<!-- 不支持 -->
<view class="overflow-auto">可滚动</view>

<!-- 替代方案 -->
<view class="overflow-hidden">隐藏溢出</view>
<!-- 或使用 scroll-view 组件 -->
<scroll-view scroll-y>可滚动内容</scroll-view>
```

**font-weight 相关类名**：
```html
<!-- 不支持 -->
<text class="font-light">细体</text>
<text class="font-extrabold">超粗</text>

<!-- 支持的字重 -->
<text class="font-normal">正常</text>
<text class="font-medium">中等</text>
<text class="font-bold">粗体</text>
```

**其他不支持的类名**：
- `flex-row-reverse`、`flex-col-reverse` - 反向排列
- `aspect-square`、`aspect-ratio-*` - 宽高比相关
- `cursor-pointer` - 光标样式
- `select-none`、`select-text` - 文本选择
- `break-words` - 文本换行
- `uppercase`、`lowercase`、`capitalize` - 文本转换
- `outline-*` - 轮廓相关（包括 `outline-none`、`outline-2`、`outline-blue-500` 等）
- `focus:*` - 聚焦状态相关（如 `focus:outline-2`、`focus:bg-red-500`）
- `active:*` - 激活状态相关（如 `active:scale-95`、`active:bg-blue-500`）
- `disabled:*` - 禁用状态相关（如 `disabled:opacity-50`、`disabled:bg-gray-400`）
- `first:*` - 第一个子元素相关（如 `first:bg-cyan-200`、`first:font-bold`）
- `last:*` - 最后一个子元素相关（如 `last:bg-yellow-200`、`last:text-red-500`）
- `hover:*` - 悬停状态相关（如 `hover-class="bg-blue-500"`、`hover-class="text-white"`）
- `visited:*` - 访问过的链接相关
- `link:*` - 未访问的链接相关
- `checked:*` - 选中状态相关（如 `checked:bg-blue-500`、`checked:border-blue-500`）
- `empty:*` - 空元素相关
- `nth-child:*` - 第n个子元素相关（如 `nth-child-2:bg-red-500`）
- `nth-of-type:*` - 第n个同类型元素相关
- `not-*` - 非选择器相关
- `before:*`、`after:*` - 伪元素相关

**颜色透明度类名**：
- `bg-opacity-*` - 背景透明度
- `text-opacity-*` - 文本透明度
- `border-opacity-*` - 边框透明度
- `divide-opacity-*` - 分割线透明度

**原因**：这些类名会生成包含 CSS 变量的颜色值，如 `rgb(x x x / var(--un-bg-opacity))`，而 uni-app x APP 不支持这种变量语法。

```html
<!-- 不支持 -->
<view class="bg-red-500 bg-opacity-50">半透明红色背景</view>
<text class="text-blue-500 text-opacity-75">半透明蓝色文字</text>

<!-- 替代方案：使用 rgba 颜色值 -->
<view style="background-color: rgba(239, 68, 68, 0.5)">半透明红色背景</view>
<text style="color: rgba(59, 130, 246, 0.75)">半透明蓝色文字</text>
```

**轮廓相关类名**：
- `outline-none` - 移除轮廓
- `outline-2`、`outline-4` - 轮廓宽度
- `outline-blue-500`、`outline-red-500` - 轮廓颜色
- `outline-dashed`、`outline-dotted` - 轮廓样式
- `outline-offset-2`、`outline-offset-4` - 轮廓偏移

**原因**：这些类名会生成 `outline-width`、`outline-color`、`outline-style`、`outline-offset` 等属性，而 uni-app x APP 不支持这些属性。

```html
<!-- 不支持 -->
<view class="outline-none">无轮廓</view>
<view class="outline-2 outline-blue-500">蓝色轮廓</view>
<view class="focus:outline-2 focus:outline-red-500">聚焦时红色轮廓</view>

<!-- 替代方案：使用 border 属性 -->
<view class="border-2 border-blue-500">使用边框替代轮廓</view>
<view class="focus:border-2 focus:border-red-500">聚焦时红色边框</view>
```

**伪类选择器相关类名**：
- `focus:*` - 聚焦状态相关（如 `focus:outline-2`、`focus:bg-red-500`）
- `active:*` - 激活状态相关（如 `active:scale-95`、`active:bg-blue-500`）
- `disabled:*` - 禁用状态相关（如 `disabled:opacity-50`、`disabled:bg-gray-400`）
- `first:*` - 第一个子元素相关（如 `first:bg-cyan-200`、`first:font-bold`）
- `last:*` - 最后一个子元素相关（如 `last:bg-yellow-200`、`last:text-red-500`）
- `hover:*` - 悬停状态相关（如 `hover-class="bg-blue-500"`、`hover-class="text-white"`）
- `visited:*` - 访问过的链接相关
- `link:*` - 未访问的链接相关
- `checked:*` - 选中状态相关（如 `checked:bg-blue-500`、`checked:border-blue-500`）
- `empty:*` - 空元素相关
- `nth-child:*` - 第n个子元素相关（如 `nth-child-2:bg-red-500`）
- `nth-of-type:*` - 第n个同类型元素相关
- `not:*` - 非选择器相关
- `before:*`、`after:*` - 伪元素相关

**原因**：这些类名会生成包含伪类选择器（`:focus`、`:active`、`:disabled` 等）或伪元素选择器（`:before`、`:after`）的 CSS 规则，而 uni-app x APP 不支持这些选择器。

#### 支持的 CSS 单位

uni-app x APP 只支持以下 CSS 单位：
- `px` 单位（像素）
- `rpx` 单位（响应式像素，750rpx = 屏幕宽度）

**说明**：uni-app x APP 不支持其他 CSS 单位，包括：
- `vh` 单位（视口高度单位，如 `100vh`）
- `vw` 单位（视口宽度单位，如 `100vw`）
- `rem` 单位（根元素字体大小单位）
- `em` 单位（父元素字体大小单位）
- `%` 单位（百分比单位）
- `cm`、`mm`、`in`、`pt`、`pc` 等其他单位

#### 视口相关类名

`h-screen`、`w-screen` 等类名会生成包含 `vh` 或 `vw` 单位的规则，因此不支持：

```html
<!-- 不支持 -->
<view class="h-screen">占满屏幕高度</view>
<view class="w-screen">占满屏幕宽度</view>
```

生成的 CSS（不支持）：
```css
.h-screen {
  height: 100vh;
}

.w-screen {
  width: 100vw;
}
```


#### Grid 相关类名

`grid-*` 系列类名会生成包含 CSS Grid 布局的规则，因此不支持：

```html
<!-- 不支持 -->
<view class="grid grid-cols-3 gap-4">
  <view>项目1</view>
  <view>项目2</view>
  <view>项目3</view>
</view>
```

#### 特殊字符类名限制

小程序和 uni-app x APP 对类名中的特殊字符有限制，括号语法 `from-[...]` 中的某些特殊字符（如 `#`）需要特殊处理。

**问题示例**：
```html
<!-- 类名会被转义 -->
<view class="from-[#f5f5f5] to-red"></view>

<!-- 实际生成的类名可能变成 -->
<view class="from-_a__a_f5f5f5_a_ to-red"></view>
```

**classCharReplace 配置说明**：

**`classCharReplace: true`**（默认）：精准匹配，只在 `class` 和 `hover-class` 属性中转换特殊字符，不会影响文本内容或其他属性
```html
<!-- 文本内容不会被转换 -->
<text class="text-sm mb-2">自定义颜色 (from-[#f5f5f5] to-red):</text>

<!-- class 属性中的特殊字符会被正确转换 -->
<view class="from-[#f5f5f5] to-[#3b82f6]"></view>
```

**`classCharReplace: 'global'`**：全局匹配，会在整个代码中替换特殊字符，**可能会错误转换文本内容**
```html
<!-- ⚠️ 文本内容也会被错误转换 -->
<text class="text-sm mb-2">自定义颜色 (from-_a__a_f5f5f5_a_ to-red):</text>
```

**`classCharReplace: false`**：禁用转换，**不支持包含特殊字符的类名**
```html
<!-- ❌ 不支持特殊字符，样式不会生效 -->
<view class="from-[#f5f5f5]"></view>
```

### 注意事项

1. **仅影响非 web 平台**：这些限制只适用于非 web 平台（如小程序、APP），不影响 web 平台
2. **编译时检查**：在 uni-app x APP 平台编译时，会检测到不支持的 CSS 选择器并报错
3. **使用 `uni-appx:` 前缀**：可以为 uni-app x APP 平台单独编写兼容的样式


## UnoCSS 局限性

由于 UnoCSS 在构建时工作，这意味着只会生成静态渲染的工具并将其发送到你的应用。可能无法检测或应用在运行时动态使用或从外部资源获取的工具。

### 不支持的场景

```html
<!-- ❌ 动态拼接的类名无法被检测 -->
<div class="p-${size}"></div>

<!-- ❌ 运时动态生成的类名无法被检测 -->
<view :class="'text-' + color"></view>

<!-- ❌ 从外部 API 获取的类名无法被检测 -->
<view :class="externalClasses"></view>
```

### 推荐的做法

```html
<!-- ✅ 使用完整的类名 -->
<div class="p-4"></div>

<!-- ✅ 使用对象语法控制类名（类名是静态的，只是条件是动态的） -->
<view :class="{ 'p-4': size === 4, 'p-8': size === 8 }"></view>

<!-- ✅ 使用数组语法（类名是静态的） -->
<view :class="['p-4', 'text-white']"></view>
```

### 使用 safelist

由于 UnoCSS 在构建时使用静态提取来工作，因此在编译时它不可能知道工具的所有组合。为此，你可以配置 `safelist` 选项来确保某些类名始终被生成，即使它们在代码中没有被检测到。

```typescript
import { defineConfig } from 'unocss'
// 优先使用 npm 包安装
import { presetUnix } from '@limeui/unocss-preset'
// 通过 uni-app 插件市场安装时使用
// import { presetUnix } from './uni_modules/lime-unocss-preset'

export default defineConfig({
	presets: [
		presetUnix()
	],
	safelist: [
		'text-red-500',
		'bg-blue-500',
		...'p-1 p-2 p-3 p-4'.split(' ')
	]
})
```

以上配置会始终生成相应的 CSS：

```css
.text-red-500 { color: rgb(239 68 68); }
.bg-blue-500 { background-color: rgb(59 130 246); }
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-3 { padding: 0.75rem; }
.p-4 { padding: 1rem; }
```

### 说明

- UnoCSS 在构建时扫描代码，生成所有可能用到的工具类
- 运时动态拼接的类名无法在构建时被检测，因此不会被生成
- 如果需要动态样式，建议使用完整的类名结合条件判断
- 对于需要完全动态样式的场景，可以考虑使用内联样式或 CSS 变量


## 致谢

感谢以下开源项目：

- [UnoCSS](https://github.com/unocss/unocss) - 提供核心原子化 CSS 引擎和大部分功能
- [unocss-applet](https://github.com/unocss-applet/unocss-applet) - 提供小程序平台支持的参考
- [@uni-helper/unocss-preset-uni](https://github.com/uni-helper/unocss-preset-uni) - 提供按平台编写样式的灵感

## 支持与赞赏

如果你觉得本插件解决了你的问题，可以考虑支持作者：

| 支付宝赞助 | 微信赞助 |
|------------|------------|
| ![](https://testingcf.jsdelivr.net/gh/liangei/image@1.9/alipay.png) | ![](https://testingcf.jsdelivr.net/gh/liangei/image@1.9/wpay.png) |