更新记录

1.0.6(2026-07-27) 下载此版本

新增

1. 分数定位(top- / right- / bottom- / left- / inset-

补全 n/m 分数形式的位置规则,任意分数自动换算百分比,覆盖 top / right / bottom / left / inset / inset-x / inset-y

写法 生成
top-1/2 top: 50%
right-1/2 right: 50%
bottom-1/2 bottom: 50%
left-1/2 left: 50%
inset-1/2 四向 50%
inset-x-1/2 左右 50%
inset-y-1/2 上下 50%
top-1/3 / left-2/3 任意分数自动换算

同步补全负值分数位置(与已有 -left-(\d+) 对称):

  • -top-1/2 / -right-1/2 / -bottom-1/2 / -left-1/2 => -50%

2. 负值任意值变换(transform

补全 -rotate-[15deg] 这类负值任意值规则(原仅有 /^-rotate-(\d+)$/,不匹配 […]):

写法 生成
-rotate-[15deg] transform: rotate(-15deg)
-scale-[1.5] transform: scale(-1.5)
-translate-x-[100px] transform: translateX(-100px)
-translate-y-[100px] transform: translateY(-100px)
-skew-x-[15deg] transform: skewX(-15deg)
-skew-y-[15deg] transform: skewY(-15deg)

顺带补全此前缺失的对称项:

  • 数字形式负值平移:-translate-x-(\d+) / -translate-y-(\d+)(含 px
  • 数字形式负值倾斜:-skew-x-(\d+) / -skew-y-(\d+)
  • 正值任意值倾斜:skew-x-[...] / skew-y-[...](原本也缺失)
<!-- 卡片扇形展开 -->
<image class="absolute bottom-20 right-1/2 mr-100 -rotate-[15deg] origin-bottom-right" />
<image class="absolute bottom-20 left-1/2  ml-100  rotate-[13deg] origin-bottom-left"  />

升级建议:使用 left-1/2 / right-1/2 / -rotate-[15deg] 等写法的项目升级到 1.0.6。

1.0.4(2026-06-17) 下载此版本

v1.0.4 (2026-06-17)

新增

1. 背景渐变(bg-*

类型 写法 示例
线性 bg-gradient-{dir}-{c1}-{c2}[-{c3}...] bg-gradient-tb-#414057-#414057
径向(默认椭圆居中) bg-radial-{c1}-{c2}... bg-radial-#fff-#000
径向(指定形状) bg-radial-{shape}-{c1}-{c2}... bg-radial-c-red-500-blue-500
径向(形状+位置) bg-radial-{shape}-{pos}-{c1}-{c2}... bg-radial-c-tl-#fff-#000
锥形 bg-conic-{c1}-{c2}... bg-conic-#f00-#0f0-#00f
  • shape:c(circle) / e(ellipse) / circle / ellipse
  • pos:c/t/b/l/r/tl/tr/bl/br/center

2. 文字渐变(text-*

通过 background-clip: text + -webkit-text-fill-color: transparent 把渐变映射到文字本身。

类型 写法 示例
线性 text-gradient-{dir}-{c1}-{c2}... text-gradient-r-#fff-#000
径向 text-radial-[{shape}-[{pos}-]]{c1}-{c2}... text-radial-c-tl-red-500-blue-500
锥形 text-conic-{c1}-{c2}... text-conic-#f00-#0f0-#00f

兼容性:H5 / 微信小程序支持;nvue 不支持伪元素与 background-clip:text,会自动降级为透明文字(建议在 nvue 端避免使用)。

3. 边框渐变(border-*

通过 border-image-source 实现,需配合 border / border-{n} 设置边框宽度。

类型 写法 示例
线性 border-gradient-{dir}-{c1}-{c2}... border-gradient-r-#fff-#000
径向 border-radial-[{shape}-[{pos}-]]{c1}-{c2}... border-radial-c-#fff-#000
锥形 border-conic-{c1}-{c2}... border-conic-#f00-#0f0-#00f

注意:border-imageborder-radius 在多数渲染端不能同时呈现圆角效果。如需「圆角 + 渐变边框」,请继续使用现有 gradientBorder 方案(伪元素裁切),并支持以下与上面同构的内联简写:

类型 写法 示例
线性 gborder-gradient-{dir}-{c1}-{c2}... gborder gborder-gradient-r-#fff-#000
径向 gborder-radial-[{shape}-[{pos}-]]{c1}-{c2}... gborder gborder-radial-c-tl-red-500-blue-500
锥形 gborder-conic-{c1}-{c2}... gborder gborder-conic-#f00-#0f0-#00f

这些类只下发 --gb-bg 变量,需配合启用类 gborder(或 gborder-after)使用;圆角沿用宿主 border-radius,宽度通过 gborder-w-* 控制。

通用方向(线性)

  • 标准:t / b / l / r / tr / tl / br / bl
  • 旧项目兼容:tb(top→bottom) / bt(bottom→top) / lr(left→right) / rl(right→left)

通用颜色支持

  • hex:#abc / #abcd / #aabbcc / #aabbccdd
  • palette 色阶:red-500blue-300primary-500...
  • 语义色:primary / secondary / success / warning / danger / info
  • 基础色:white / black / transparent / current

多色(≥2 色)按位置等分自动均匀分布。

升级建议:需要使用径向 / 锥形 / 文字渐变 / 边框渐变内联简写的项目升级到 1.0.4。

1.0.3(2026-06-15) 下载此版本

v1.0.3 (2026-06-15)

修复

  • 修复热更新部分样式丢失问题

    • 现象:开发态下编辑源码触发 HMR 后,部分新增/修改的原子类样式未出现在最终页面,需重启 dev 服务才能生效。
    • 修复:完善 HMR 流程下 CSS 模块缓存的失效策略,确保增量编译后 generated.css 的最新内容能被正确推送到客户端。
  • 修复其它已知 bug

    • 修复在特定类名组合下匹配优先级异常导致的样式不生效问题。
    • 修复个别正则在边界场景下命中后续规则的误判。

新增

  • 背景图任意值语法 bg-[url(...)]

    • 支持直接通过任意值写入背景图地址,自动去除引号并输出 background-image: url('...')
    • 用法:bg-[url(/static/bg.png)]
  • 多层 gradient 任意值叠加 bg-[linear-gradient(...)] / bg-[radial-gradient(...)] / bg-[conic-gradient(...)]

    • 兼容 repeating- 前缀,支持「多层 gradient 用逗号叠加」。
    • 类名中无法直接写空格,约定用 _ 代替(如 to_right135deg_0%),输出 CSS 时还原成空格。
    • 示例:bg-[radial-gradient(130rpx_at_bottom,#fbbafe_0%,transparent_70%),linear-gradient(81deg,#e3d1ff_0%,#b9b2fe_37%,#a7c1ff_100%)]
  • 背景颜色任意值兜底 bg-[...]

    • bg-[#xxx] / bg-[rgba(...)] / bg-[hsl(...)] / bg-[red] 等统一映射为 background-color
    • 内部已对 url(...)*-gradient(...) 优先匹配,兜底规则不会误命中。
  • 渐变中间色 via-{color}-{shade}

    • 设置 --gradient-via CSS 变量,与 from-* / to-* 配合可生成三色渐变。
    • 在未指定 via-* 时,bg-gradient-to-* 自动回退为两色渐变(中间色等于起始色)。
  • 背景尺寸任意值 bg-size-[...]

    • 支持 bg-size-[100%_auto] / bg-size-[200rpx_100rpx] / bg-size-[50%]_ 自动还原为空格。
  • 背景位置任意值 bg-pos-[...]

    • 支持 bg-pos-[center_top] / bg-pos-[10rpx_20rpx]_ 自动还原为空格。
  • 固定背景方案 bg-sticky / bg-sticky-parent / bg-sticky-content

    • 在长滚动页面中让背景图脱离滚动流。
    • 用法:父容器加 bg-sticky-parent,背景元素加 bg-sticky,内容元素加 bg-sticky-content
    • 原理:背景层 position:fixed 铺满视口,z-index:0;内容层 position:relativez-index:1 自然层叠在背景之上(不使用 z-index:-1,避免被祖先不透明背景遮盖)。
  • 单标签固定背景方案 bg-fixed-img

    • 用法:<view class="bg-fixed-img bg-[url(...)] bg-cover bg-center bg-no-repeat" />
    • 原理:通过 ::after 伪元素以 inherit 继承宿主的所有 background-* 属性,并用 position:fixed 铺满视口,自动实现「背景固定不滚动」;直接子节点自动获得 z-index:1,确保压在背景之上。
    • 限制:仅 H5 / App-Vue 端有效(小程序与 App-Nvue 不支持伪元素)。
  • 背景位置语义类 bg-bottom-center / bg-top-center

    • bg-bottom-centerbackground-position: center bottom
    • bg-top-centerbackground-position: center top
    • 与已有的 bg-left-top / bg-right-bottom 等保持命名一致。
查看更多

平台兼容性

uni-app(4.65)

Vue2 Vue3 Chrome Chrome插件版本 Safari Safari插件版本 app-vue app-nvue Android Android插件版本 iOS iOS插件版本 鸿蒙
- 1.0.0 1.0.0 × 1.0.0 1.0.0
微信小程序 微信小程序插件版本 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
1.0.0 - - - - - - - - - - -

jz-uoscss

专为 uni-app 设计的原子化 CSS 构建插件。基于 Vite 构建时预编译,零运行时开销,全端兼容(H5 / 小程序 / App-Vue / App-Nvue)。

version license


目录


核心特性

特性 说明
Vite 构建时预编译 构建期生成 generated.css,零运行时开销
JS 动态类名提取 自动从 <script>.js/.ts 文件中提取类名
无限维度主题 任意数量主题维度(品牌、会员、性别、明暗、地区……),且前缀顺序无关
背景图简写 bg-[url(name)] 自动补全根路径与扩展名
平台条件编译 自动识别 H5 / 小程序 / nvue 不兼容的 CSS,用 #ifdef / #ifndef 包裹
多端兼容 H5、微信/支付宝/百度/字节/QQ/钉钉小程序、App-Vue、App-Nvue
HMR 热更新 修改源码或规则文件自动重新生成 CSS
类名转义 自动处理小程序不允许的特殊字符(/:#.%[]()

快速开始

1. 安装

jz-uoscss 放到项目的 src/uni_modules/ 目录下。

2. 注册 Vite 插件

// vite.config.ts
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import jzUoscssPlugin from './src/uni_modules/jz-uoscss/vite-plugin.js'

export default defineConfig(() => ({
  plugins: [
    uni(),
    jzUoscssPlugin({
      // 可选:动态拼接的类名兜底
      safelist: ['flex-center', 'btn-primary'],
      // 可选:排除目录
      excludes: ['src/pages/legacy'],
      // 可选:扫描 JS/TS 文件
      scanJS: true,
      // 可选:多维度主题
      compositeThemes: {
        dimensions: {
          gender: ['male', 'female'],
          mode: ['light', 'dark'],
        },
      },
      // 可选:背景图简写
      backgroundImage: {
        basePath: '/static/images/common',
        defaultExtension: '.png',
      },
    }),
  ],
}))

3. 引入生成的 CSS

// src/main.ts
import { createSSRApp } from 'vue'
import App from './App.vue'

// @ts-ignore
import '@/uni_modules/jz-uoscss/generated.css'

export function createApp() {
  const app = createSSRApp(App)
  return { app }
}

4. 在模板中使用

<template>
  <view class="w-full h-100 p-20 m-10 rounded-8 bg-primary">
    <text class="text-16 text-white font-bold">Hello jz-uoscss</text>
  </view>
</template>

Vite 插件配置

jzUoscssPlugin(options)
参数 类型 默认值 说明
safelist string[] [] 强制包含的类名(即使源码中未出现也会生成)
safelistFn (ctx) => string[] null 函数式 safelist,可访问 theme / rules / shortcuts
safelistPatterns RegExp[] [] 模式 safelist,按规则名匹配
excludes string[] [] 排除扫描的目录路径(字符串包含匹配)
scanJS boolean true 是否扫描 .js/.ts/.jsx/.tsx 文件提取类名
jsIncludes string[] [] 仅扫描这些目录下的 JS/TS 文件
jsExcludes string[] [] 排除这些目录下的 JS/TS 文件
themeVariants Object {} 自定义主题前缀映射 { prefix: dataThemeValue }
compositeThemes Object {} 多维度主题配置 { dimensions: { dim: [values] } }
backgroundImage Object {} 背景图简写 { basePath, defaultExtension }
colors Object {} 自定义颜色(用于调色板枚举)

常用类名

基础类

类别 示例
间距 p-10 px-30 py-16 m-10 mt-20 -mt-10(负值)
尺寸 w-100 h-100 w-full min-w-100 max-h-300
Flex flex flex-col items-center justify-center flex-1 gap-10
颜色 bg-primary bg-white text-primary text-white bg-red-500
边框 border border-2 border-primary rounded-8 rounded-full
阴影 shadow shadow-md shadow-lg
文字 text-16 text-center font-bold leading-1.5 truncate
定位 absolute relative top-0 inset-0 z-10 left-1/2 -left-1/2
动画 transition duration-300 scale-105 -rotate-[15deg] rotate-[13deg]
布局 block flex grid hidden
视觉 opacity-50 cursor-pointer select-none

数值默认单位为 rpx,例如 w-100 = width: 100rpx

实体类(开箱即用的组件级简写)

buttons / cards / inputs / badges / avatars / dividers / skeletons /
masks / toasts / tags / flex / layouts / positions / borders / media / texts
<view class="btn btn-primary">主按钮</view>
<view class="card">卡片</view>
<view class="badge badge-success">成功</view>
<view class="flex-center">居中容器</view>

前缀系统

前缀类型 示例 说明
断点 sm: md: lg: xl: 响应式 @media (min-width)
内置主题 light: dark: 明暗主题
自定义主题 male: female: ocean: 通过 compositeThemes 注册
伪类 hover: active: focus: disabled: 状态变体

支持任意组合:

<view class="sm:dark:hover:bg-primary">响应式 + 主题 + 伪类</view>
<view class="male:dark:hover:bg-blue-600">多维度 + 伪类</view>

JS 中使用类名

插件会自动扫描 <script>.js/.ts 文件中的类名字符串:

<script setup>
// ✅ 字符串字面量
const btnClass = 'px-30 py-16 rounded-8 bg-primary text-white'

// ✅ 三元表达式
const cls = computed(() => isActive ? 'bg-primary text-white' : 'bg-gray')

// ✅ 模板字符串静态部分
const label = `bg-blue-500 text-white px-${size}`
</script>

动态拼接的类名

bg-${color}-500 这类变量值无法静态分析,请通过以下方式兜底:

jzUoscssPlugin({
  // 方式 1:直接列出
  safelist: ['bg-primary', 'btn-primary'],

  // 方式 2:函数式
  safelistFn: ({ theme }) => {
    const list = []
    for (const c of theme.colors || []) list.push(`bg-${c}-500`, `text-${c}-500`)
    return list
  },

  // 方式 3:正则
  safelistPatterns: [
    /^bg-(primary|secondary|success|warning|danger)$/,
  ],
})

或在代码中加注释精准声明:

<script setup>
// @dynamic-css-include
const classes = {
  primary: 'bg-primary text-white',
  secondary: 'bg-secondary text-white',
}
</script>

无限维度主题

支持任意数量主题维度,前缀顺序无关——vip:male:dark:bg-gold-500dark:male:vip:bg-gold-500 生成完全相同的 CSS。

配置

jzUoscssPlugin({
  compositeThemes: {
    dimensions: {
      brand: ['nike', 'adidas', 'puma'],
      vip: ['gold', 'silver', 'normal'],
      gender: ['male', 'female'],
      mode: ['light', 'dark'],
      region: ['cn', 'us', 'eu'],
    },
  },
})

使用

<!-- 多维度任意顺序,效果一致 -->
<text class="nike:gold:male:dark:cn:bg-red-500">五维并存</text>
<text class="cn:dark:male:gold:nike:bg-red-500">同上,顺序不同</text>

<!-- 部分维度 -->
<text class="nike:dark:bg-blue-600">品牌+暗色</text>
<text class="dark:text-white">仅暗色</text>

运行时切换

import {
  initDimensionConfig,
  setDimension,
  getDimension,
  getAllDimensions,
  getDimensionClasses,
} from '@/uni_modules/jz-uoscss'

// 1. 注入维度配置(main.ts / App.vue 中)
initDimensionConfig({
  dimensions: {
    gender: ['male', 'female'],
    mode: ['light', 'dark'],
  },
})

// 2. 切换(自动挂载 theme-male / theme-dark 到根元素)
setDimension('gender', 'male')
setDimension('mode', 'dark')

// 3. 读取
getDimension('gender')        // → 'male'
getAllDimensions()            // → { gender: 'male', mode: 'dark' }
getDimensionClasses()         // → 'theme-male theme-dark'

背景图简写

避免冗长的图片路径:

<!-- 旧写法 -->
<view class="bg-[url(/static/images/common/background.png)] bg-cover bg-center">

<!-- 新写法 -->
<view class="bg-[url(background)] bg-cover bg-center">

配置

jzUoscssPlugin({
  backgroundImage: {
    basePath: '/static/images/common',  // 默认 '/static/images'
    defaultExtension: '.png',           // 默认 '.png'
  },
})

解析规则

写法 解析为
bg-[url(background)] url('/static/images/common/background.png')
bg-[url(/group/background)] url('/static/images/common/group/background.png')
bg-[url(/group/img.jpg)] url('/static/images/common/group/img.jpg')(保留原后缀)
bg-[url(/static/other/img.png)] url('/static/other/img.png')(绝对路径不拼接)

不配置 backgroundImage 时,bg-[url(...)] 行为与原生写法一致。

与主题前缀组合

<view class="dark:bg-[url(background)]"></view>
<view class="male:light:bg-[url(avatar-male)]"></view>
<view class="female:dark:bg-[url(/avatars/avatar-f.jpg)]"></view>

类名转义说明

小程序 class 不允许特殊字符,构建时会自动同步转义 DOM class 与 CSS 选择器:

原字符 转义后 示例
/ -s111- w-1/2.w-1-s111-2
: -c111- hover:bg-red.hover-c111-bg-red:hover
# -h111- bg-#F5F6FA.bg--h111-F5F6FA
. -d111- bg-primary-1.5.bg-primary-1-d111-5
% -pc111- w-50%.w-50-pc111-
[ ] ( ) -b111- -e111- -p111- -q111- bg-[url(x)]

使用者无需感知此过程——只要按正常类名写法书写,插件会自动处理。


运行时 API(仅 H5)

小程序与 App 必须使用构建时方案。运行时 API 仅适用于 H5 的特殊动态场景。

import {
  // 动态 CSS
  setupDynamicCSS,         // H5 运行时初始化
  install,                 // Vue 插件安装
  generate,                // 手动生成 CSS 字符串
  ensureClasses,           // 确保类名 CSS 已生成
  addRule,                 // 动态添加规则
  addShortcut,             // 动态添加 shortcut

  // 多维度主题
  initDimensionConfig,
  setDimension,
  getDimension,
  initDimensions,
  getAllDimensions,
  getDimensionClasses,

  // 主题
  presetThemes, lightTheme, darkTheme,
  createCustomTheme, registerTheme, getTheme,

  // 预设
  presetWeapp, presetCommon,
} from '@/uni_modules/jz-uoscss'

Vue 插件用法(H5)

import { createSSRApp } from 'vue'
import App from './App.vue'
import jzUoscss from '@/uni_modules/jz-uoscss'

export function createApp() {
  const app = createSSRApp(App)
  app.use(jzUoscss, {
    rules: [[/^p-(\d+)$/, ([, d]) => ({ padding: `${d}rpx` })]],
    shortcuts: [['flex-center', 'flex items-center justify-center']],
    safelist: ['flex-center'],
  })
  return { app }
}

显式声明动态类名

import { ensureClasses } from '@/uni_modules/jz-uoscss'

ensureClasses(['bg-primary', 'text-white', 'px-30', 'py-16'])

常见问题

Q1:动态拼接的类名(bg-${color}-500)能识别吗?

部分能。模板字符串的静态部分会被识别,${...} 内的变量值无法静态分析。请使用 safelistFn / safelistPatterns 枚举所有可能值,或加 // @dynamic-css-include 标注。

Q2:小程序为什么必须使用构建时方案?

小程序运行环境不支持 document.createElement('style') 等 DOM API,无法运行时注入样式。所有样式必须在编译期就生成在 .wxss / .acss 中。

Q3:nvue 项目可以使用吗?

可以。插件会自动跳过 nvue 不支持的规则(vw/vh/%grid-*background-imagebox-shadow 等)。但 nvue 仅支持 Flex 布局 + 部分 CSS 属性,建议优先使用 flex 系列与 rpx 单位。

Q4:HMR 修改后样式没生效?

插件在 CSS 重新生成后会自动失效 Vite 模块缓存并触发整页刷新。如仍未生效,请确认:

  • main.tsimport '@/uni_modules/jz-uoscss/generated.css'
  • Vite 插件已正确注册(应在 uni() 之后)

Q5:uni.navigateTo({ url: '/pages/...' }) 跳转失败?

请确认插件版本 ≥ 1.0.1。1.0.0 中存在路径字符串被误转义的 bug,1.0.1 已修复。

Q6:能与 Tailwind / UnoCSS 共存吗?

可以并行使用,但不推荐。两者类名空间会冲突,且 jz-uoscss 的转义规则(/-s111-)会改写所有含特殊字符的 class,可能与其它框架的输出不兼容。


许可证

MIT License

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。