ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

airi 项目 UnoCSS 实战:用 transformerDirectives 在 CSS 中原生启用 @apply、@screen、theme() 与 icon()

airi 项目 UnoCSS 实战:用 transformerDirectives 在 CSS 中原生启用 @apply、@screen、theme() 与 icon() airi 项目 UnoCSS 实战用 transformerDirectives 在 CSS 中原生启用 apply、screen、theme() 与 icon()【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airitransformerDirectives 是 UnoCSS 提供的一个核心 transformer它让开发者能够直接在 CSS 中书写apply、screen、theme()与icon()四种指令把工具类utilities与主题theme能力搬进普通 CSS 文件中。在 airi 仓库中这条能力既被根配置集中启用uno.config.ts也被应用到桌面端渲染层如 spotlight.vue的复杂渐变与响应式样式编写上。读完本文你将掌握四种指令的完整语法、别名配置方法以及如何像 airi 一样在 Vue SFC 的 scoped style 里优雅地混用工具类与原生 CSS。本文的原始知识卡位于仓库 .agents/skills/unocss/references/transformer-directives.md下面结合 airi 的真实配置与源码逐层展开。transformerDirectives 解决的问题在纯 UnoCSS 工作流中工具类通常直接写在模板的 class 属性中。但当你需要复用一组工具类、或想在::before/::after等伪元素、keyframes内部、媒体查询里组合样式时模板 class 就无能为力了。transformerDirectives 正是为此而生——它扫描 CSS 源码把指令转换为展开后的工具类声明使样式逻辑收敛到 CSS与工具类按需生成两种范式可以共存。安装与最小配置非常简单在 UnoCSS 配置文件通常是uno.config.ts中加入 transformer 即可import { defineConfig, transformerDirectives } from unocss export default defineConfig({ transformers: [ transformerDirectives(), ], })airi 中的启用方式从根配置到各应用共享airi 的根级 uno.config.ts 把共享配置封装为sharedUnoConfig()其中 transformers 同时启用了 directives 与 variant group 两个转换器并对别名做了显式限定// 根 uno.config.ts节选 transformers: [ transformerDirectives({ applyVariable: [--at-apply], }), transformerVariantGroup(), ],这里的关键点显式传入applyVariable: [--at-apply]后自定义属性别名只保留--at-apply一个不再包含默认同义别名详见下文别名一节。随后不同子应用通过mergeConfigs复用这份共享配置——例如 packages/stage-ui/uno.config.ts 直接合并了根配置import { defineConfig, mergeConfigs } from unocss import { histoireUnoConfig, sharedUnoConfig } from ../../uno.config export default mergeConfigs([ sharedUnoConfig(), histoireUnoConfig(), defineConfig({}), ])也有的应用独立声明完整配置例如 apps/component-calling/uno.config.ts 中与transformerVariantGroup()并排启用了默认形态的transformerDirectives()不传参数。仓库通过 pnpm workspace catalog 统一锁定了unocss版本见 pnpm-workspace.yaml 中unocss: 66.7.5的 catalog 条目因此各应用获得的 transformer 行为是一致的。apply在 CSS 中内联工具类基础用法与带变体的写法apply可以把一组工具类合并进任意 CSS 规则中最直接的应用是封装类组件化的样式.custom-btn { apply py-2 px-4 font-semibold rounded-lg; }当需要混入hover:、focus:等**变体variant**时由于变体值中带冒号与空格必须使用引号包裹整个字符串否则指令解析会失败.custom-btn { apply hover:bg-blue-600 focus:ring-2; }CSS 自定义属性替代写法vanilla CSS 兼容apply是标准 CSS 之外的指令语法若希望样式文件仍能通过普通 CSS 解析器例如防止原生 CSS 校验报错或希望渐进增强可改用 CSS 自定义属性别名.custom-div { --at-apply: text-center my-0 font-medium; }transformer 支持三个同义别名配置如下transformerDirectives({ applyVariable: [--at-apply, --uno-apply, --uno], // 或完全关闭别名能力applyVariable: false })默认别名是--at-apply当传入数组时数组内容即生效别名集合设为false可关闭该特性若你的样式表中恰好有用到这些自定义属性的场景可避免误展开。airi 的真实用法伪元素 复杂渐变 深色模式自定义属性写法在 airi 桌面端被大量使用因为它能出现在::before/::after这类伪元素规则中与手写 position、mask-image 等原生属性无缝共存。下面摘自已搜索可见的 apps/stage-tamagotchi/src/renderer/pages/spotlight.vue舞台 spotlight 输入框的光晕层.spotlight-card::before { pointer-events: none; --at-apply: bg-gradient-to-r from-primary-500/25 via-primary-500/12 to-transparent dark:from-primary-400/25 dark:via-primary-400/12 dark:to-transparent; content: ; position: absolute; inset: 0; z-index: 0; width: 85%; height: 100%; mask-image: linear-gradient(120deg, white 100%); } .spotlight-card::after { pointer-events: none; --at-apply: bg-dotted-[primary-300/35] dark:bg-dotted-[primary-200/16]; position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; background-size: 10px 10px; content: ; mask-image: linear-gradient(165deg, white 30%, transparent 55%); }这个例子至少说明了三点实战要点值必须带引号多段工具类含空格与dark:变体必须写成引号字符串--at-apply后的值才会被当作完整指令解析可以消费自定义规则与主题色bg-dotted-[primary-300/35]对应根配置 uno.config.ts 中自定义的bg-dotted-[...]规则而primary-300等色板来自presetChromatic生成的主题——证明--at-apply展开的是与模板 class 完全一致的完整工具类体系原生 CSS 与指令可并存同一规则内mask-image、background-size、position等手写声明与--at-apply互不干扰这让UI 引擎层样式保持为可读的 CSS。另一个更简洁的用法见 apps/stage-tamagotchi/src/renderer/pages/index.vue加载动效墙.wall { --at-apply: text-primary-300; --wall-width: 8px; animation: wall-move 1s linear infinite; background-image: repeating-linear-gradient( 45deg, currentColor, currentColor var(--wall-width), #ff00 var(--wall-width), #ff00 calc(var(--wall-width) * 2) ); }这里--at-apply: text-primary-300仅为元素注入文字颜色随后手写的background-image通过currentColor引用它——指令与原生 CSS 通过颜色关键字协同工作是工具类用于取主题 token、原生 CSS 负责复杂绘制的理想分工。提示从源码检索看airi 的 Vue SFC 中统一采用--at-apply别名而非apply关键字。若团队规约更看重可迁移性可采用与根配置一致的applyVariable显式列表避免样式被其他解析器误读。screen把断点写成语义化的媒体查询screen 断点名会被转换为对应的媒体查询断点名称来自主题breakpointspresetWind3 / preset-mini 默认提供sm/md/lg/xl/2xl等。经典响应式栅格示例.grid { display: grid; grid-template-columns: repeat(2, 1fr); } screen sm { .grid { grid-template-columns: repeat(3, 1fr); } } screen lg { .grid { grid-template-columns: repeat(4, 1fr); } }相比手写媒体查询screen的可读性更强且断点值始终与主题定义保持单一事实来源。断点变体lt- 与 at-除默认的大于等于某断点语义外还支持两种变体/* 小于某断点才生效max-width 语义 */ screen lt-sm { .item { display: none; } } /* 仅在该断点区间生效min/max 组合 */ screen at-md { .item { width: 50%; } }这在移动端隐藏某元素仅中屏横排等场景中比默认的向上兼容语义更精确。theme()在任意 CSS 属性中读取主题令牌theme(路径点分字符串)允许在 CSS 值里直接读取 UnoCSS 主题配置避免把colors.blue.500这类十六进制硬编码散落在样式文件中.btn-blue { background-color: theme(colors.blue.500); padding: theme(spacing.4); border-radius: theme(borderRadius.lg); }取值路径采用点分记号映射到根配置defineConfig({ theme: {...} })的对象结构。airi 根配置扩展了丰富的主题段见 uno.config.ts例如theme.fontFamily中定义的cute/cutejp/sans-rounded等字体族、以及theme.animation下一整套 keyframes / durations / timingFns 的入场退场动画配置——这些都可以通过theme(fontFamily.cute)、theme(animation.durations.fadeIn)这类写法在 CSS 中引用与apply、模板 class 读取的是同一份主题数据。icon()把图标工具类转成 SVG 背景图icon()指令能把预设图标工具类如i-carbon-sun转换为内联 SVGbackground-image。它依赖 preset-icons 提供图标解析——airi 根配置恰好启用了presetIcons并挂载了多个 Iconify 集合见 uno.config.ts.icon-sun { background-image: icon(i-carbon-sun); } /* 第二个参数指定自定义颜色 */ .icon-moon { background-image: icon(i-carbon-moon, #fff); } /* 颜色参数同样支持 theme() 读取主题色 */ .icon-alert { background-image: icon(i-carbon-warning, theme(colors.red.500)); }注意两点颜色的使用方式是覆盖图标原色本质是为内联 SVG 注入指定色值而theme(colors.red.500)之所以用双引号是因为它嵌套在外层单引号之内且颜色参数本身是一个表达式而非普通字符串。该能力非常适合为那些无法通过text-*染色的背景型图标注入主题色。完整组合示例Card 组件把四种指令放进一个组件级样式即可看到它们如何协作完整示例亦保留于原始知识卡.card { apply rounded-lg shadow-md p-4; background-color: theme(colors.white); } .card-header { apply font-bold text-lg border-b; padding-bottom: theme(spacing.2); } screen md { .card { apply flex gap-4; } } .card-icon { background-image: icon(i-carbon-document); apply w-6 h-6; }从这份示例可以归纳协作模式apply负责排版骨架与可见性theme()负责取值screen负责响应式分段icon()负责图形资产。在 airi 这类多端Web / Electron / Capacitor / tamagotchi 桌面应用monorepo 中把这份 CSS 放在公共 UI 包如 packages/stage-ui内配合根配置的分层启用策略即可保证各端获得一致的指令行为。使用建议与注意事项作用域内使用在 Vue SFC 中style scoped内的apply/--at-apply展开发生在 UnoCSS 构建阶段Vue 的 scoped 属性处理与其并不冲突airi 的多个页面即采用这种组合。带空格与变体务必加引号apply与--at-apply的值若包含hover:/dark:/ 空格分隔的多段类名必须整体加引号否则会被当作单一工具类解析失败。别名的统一管理既然项目从根配置统一了applyVariable新增子应用时应优先复用sharedUnoConfig()或与其保持一致避免不同应用间别名集合漂移。图标类需存在集合icon()依赖presetIcons及其配置的 collections如果图标名不在已加载集合内构建期不会生成对应背景图。与 extractor 的配合apply/--at-apply等指令内出现的工具类由 transformer 收集并触发生成airi 根配置的 content pipeline见 uno.config.ts同时覆盖.vue、.ts/.js等文件确保 CSS 中引用的类与模板中用到的类都进入统一扫描范围。若需进一步了解相关的 preset-icons、preset-wind3、variant-group 与 shortcuts 能力可继续查阅仓库 .agents/skills/unocss 下的 references 知识卡如 preset-icons.md、preset-wind3.md、transformer-variant-group.md、core-shortcuts.md它们与本文共同构成 UnoCSS 在 airi 中的完整使用参考。【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表