ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

UnoCSS presetWind3 预设深度解析:在 airi 项目中落地 Tailwind / Windi 兼容的原子化 CSS

UnoCSS presetWind3 预设深度解析:在 airi 项目中落地 Tailwind / Windi 兼容的原子化 CSS UnoCSS presetWind3 预设深度解析在 airi 项目中落地 Tailwind / Windi 兼容的原子化 CSS【免费下载链接】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/airiunocss/preset-wind3是 UnoCSS 官方提供的、兼容 Tailwind CSS v3 与 Windi CSS 语法的主力预设也是本仓库中web / macOS / Windows / mobile等各端 UI 统一采用的样式基础。本文以该预设的官方参考文档为骨架结合 airi monorepo 内真实的 UnoCSS 配置文件与 Vue 组件用法系统讲解其安装、特性、暗色模式、可配置项以及它相对于 Tailwind / Windi 的关键语法差异与实验性能力帮助你在一套配置下写出既熟悉又高效的工具类样式。一、presetWind3 是什么关联文档preset-wind3.mdpresetWind3 是Tailwind CSS / Windi CSS 兼容预设被官方标注为 UnoCSS 中最常用的预设The most commonly used preset for UnoCSS。它把 Tailwind CSS v3 和 Windi CSS 两套生态的类名语法映射到 UnoCSS 按需生成的原子化 CSS 引擎之上从而让熟悉这两套框架的开发者无需学习新语法即可迁移。在使用它之前需要确认两个背景事实UnoCSS 的核心本身是无观点un-opinionated的所有工具类都来自预设presetWind3 正是默认能力最全的入口预设。由于 UnoCSS 遵循Tailwind CSS v3 的命名约定你在 SKILL.md 中可以看到官方 skill 明确建议 agent 在写 UnoCSS 前先检查项目根目录的uno.config.*或unocss.config.*了解可用的 presets、rules 与 shortcuts 后再动手。本仓库的pnpm-lock.yaml锁定的是unocss66.7.5因此下文描述以当前仓库实际依赖的 UnoCSS 66.x 行为为准。二、安装与基础配置在你的 UnoCSS 配置文件中启用 presetWind3 即可import { defineConfig, presetWind3 } from unocss export default defineConfig({ presets: [ presetWind3(), ], })注意官方文档明确指出unocss/preset-uno与unocss/preset-wind已被废弃deprecated统一更名为unocss/preset-wind3。如果你的项目历史配置中仍引用前两者应直接替换为presetWind3其 API 与默认行为一致。在 airi 仓库中几乎所有子项目都通过这一入口启用该预设例如根目录 uno.config.tssharedUnoConfig()中presetWind3()与presetAttributify()、presetTypography()、presetIcons()一起注册并配套transformerDirectives、transformerVariantGroup两个 transformerdocs 站点 uno.config.ts为内容型文档站点单独注册presetWind3()apps/component-calling/uno.config.ts组件演示应用同样直接注册presetWind3()。也就是说一个仓库、一套 Wind3 语法分端复用是当前项目的通用组织方式。三、核心特性一览根据官方参考文档presetWind3 提供以下能力完整的 Tailwind CSS v3 兼容性类名、默认色板、默认间距体系与 Tailwind 对齐暗色模式支持dark:与dark:两种变体写法全量响应式变体sm:、md:、lg:、xl:、2xl:全量标准工具类flex、grid、spacing、colors、typography 等动画支持内置 Animate.css 动画集。在此基础上它还保留了 Windi CSS 部分特色的迁移路径见下文与 Windi CSS 的差异这正是它被大量从 Windi 或 Tailwind 迁移的项目选为默认预设的原因。四、暗色模式三种策略的完整对比暗色模式是组件库与站点样式绕不开的话题。presetWind3 提供三种互有取舍的暗色实现方式其中前两者通过配置项dark切换。4.1 基于 class 的策略默认不传任何选项时即为 class 策略此时dark:变体生成的 CSS 选择器依赖某个祖先节点带有.darkclassdiv classdark:bg-gray-800生成结果为.dark .dark\:bg-gray-800 { ... }这也是本仓库绝大多数场景采用的方式。例如 packages/stage-ui 中的登录面板用dark:bg-white dark:text-neutral-950反色显示而 property-point.vue 通过bg-red-100/50 dark:bg-red-900/50为明暗两套主题提供不同的拖动状态背景。同时docs/uno.config.ts 中的排版预设通过.dark a、.dark details选择器定制暗色下正文链接与折叠面板的配色其 HTML 根节点即由站点负责挂上.dark。4.2 基于 media query 的策略如果希望跟随系统外观而非手动切换可配置为mediapresetWind3({ dark: media })此时dark:变体不再依赖 class而是直接生成media (prefers-color-scheme: dark) { ... }4.3 自定义选择器策略dark选项还支持对象形式显式指定明暗两组 class 名presetWind3({ dark: { light: .light, dark: .dark } })4.4 Opt-in Media Querydark:与上述配置无关UnoCSS 额外提供dark:前缀无论dark配置如何都强制按系统偏好生成div classdark:bg-gray-800这适合个别元素跟随系统、整体跟随站点开关的混合场景例如本仓库 UI 中希望同时支持手动亮/暗与prefers-color-scheme的特殊组件。五、Options 选项逐项说明官方参考文档给出了 presetWind3 的完整选项骨架presetWind3({ // Dark mode strategy dark: class, // class | media | { light: .light, dark: .dark } // Generate pseudo selector as [group] instead of .group attributifyPseudo: false, // CSS custom properties prefix variablePrefix: un-, // Utils prefix prefix: , // Generate preflight CSS preflight: true, // true | false | on-demand // Mark all utilities as !important important: false, // boolean | string (selector) })各项语义说明选项默认值类型作用darkclassclass \| media \| { light, dark }决定dark:变体的编译策略见上文第四节attributifyPseudofalseboolean与 attributify 预设配合时将伪类选择器从.group:hover形式的 class 改生成[group]属性选择器形式variablePrefixun-string生成的 CSS 自定义属性前缀默认如--un-bg-opacityprefixstring为所有工具类增加统一前缀例如传airi-后需写作airi-flexpreflighttrueboolean \| on-demand是否生成 Tailwind 风格的基础重置样式on-demand只生成实际使用到元素的 preflightimportantfalseboolean \| string是否为所有工具类追加!important见 5.1 节5.1 important 选项详解当第三方组件样式优先级过高、需要让工具类强制覆盖时可全量开启presetWind3({ important: true, })另一种更推荐的做法是用选择器提升优先级而不用!important——传入一个选择器字符串后UnoCSS 会将其作为作用域包一层presetWind3({ important: #app, })输出形如#app :is(.dark .dark\:bg-blue) { ... }这种方式既避开了!important难以继续覆盖的问题又把冲突范围收窄到#app容器内适合本仓库这类UI 库packages/stage-ui与宿主 Appapps/*多层样式并存的架构。六、与 Tailwind CSS 的差异迁移必读presetWind3 虽以兼容 Tailwind CSS v3为目标但由于 UnoCSS 的词法提取器extractor与实现细节不同仍存在三处必须知道的差异。6.1 模板引号写法不受支持由于 extractor 的取词方式类名中不能直接出现引号字符下面的 Tailwind 写法在 UnoCSS 中不会生效!-- Wont work -- div classbefore:content-[]官方给出的替代方案是改用 shortcut / 语义类名!-- Use shortcut instead -- div classbefore:content-empty你可以把这类语义名在shortcuts或自定义 rules 中实现可参考 根 uno.config.ts 中通过正则 rule 扩展现有语法的做法。6.2 Background Position 需要position:前缀Tailwind 对自定义背景定位允许省略类型前缀直接写任意值而 UnoCSS 必须显式声明类型以避免歧义!-- Tailwind -- div classbg-[center_top_1rem] !-- UnoCSS -- div classbg-[position:center_top_1rem]6.3 动画内置 Animate.css冲突用-alt后缀presetWind3 直接集成了Animate.css动画集。当同一动画名在 Tailwind 与 Animate.css 中都存在时UnoCSS 用-alt后缀区分animate-bounce—— Tailwind 版本animate-bounce-alt—— Animate.css 版本如果需要自定义动画则通过theme.animation的四个子段分别定义关键帧、时长、缓动与播放次数theme: { animation: { keyframes: { custom: {0%, 100% { opacity: 0; } 50% { opacity: 1; }}, }, durations: { custom: 1s, }, timingFns: { custom: ease-in-out, }, counts: { custom: infinite, }, } }这是一个真实可落地的例子airi 根配置在 uno.config.ts 中通过完全相同的theme.animation结构定义了overlayShow、contentShow、slideUpAndFade、fadeIn等一组面向弹层/提示的动画并为它们分别声明了durations如contentShow: 150ms与timingFnscubic-bezier(0.16, 1, 0.3, 1)随后组件里直接使用类似animate-contentShow的类名。这说明本仓库的动效体系正是建立在 presetWind3 的扩展动画机制之上。七、与 Windi CSS 的差异迁移对照从 Windi CSS 迁移过来的项目需要先习惯三组变体命名的变化Windi CSSUnoCSSsm:p-1lt-sm:p-1lg:p-1at-lg:p-1xl:p-1xl:p-1此外方括号语法中的分隔符从逗号改为下划线!-- Windi CSS -- div classgrid-cols-[1fr,10px,max-content] !-- UnoCSS -- div classgrid-cols-[1fr_10px_max-content]结合 6.2 节可知UnoCSS 的任意值语法统一遵循方括号 下划线代替空格、必要时加类型前缀的规则同样根 uno.config.ts 中自定义的mask-[...]rule 内部实现也用suffix.replace(/_/g, )把下划线还原为空格与这一约定保持一致。八、实验性媒体悬停Media Hover针对触屏设备上点击后 hover 样式粘滞sticky hover这一经典问题presetWind3 提供了实验性的hover:变体。它与dark:一样是 opt-in 的不依赖任何配置div classhover-text-red生成逻辑会把规则包进支持精确指针设备的媒体查询中media (hover: hover) and (pointer: fine) { .\hover-text-red:hover { ... } }这在 airi 这类同时覆盖桌面Electron与移动端Capacitor的跨端 UI 场景中非常实用——桌面端保留 hover 反馈移动端则彻底消除误触残留状态。仓库根配置里甚至存在一个名为presetStoryMockHover的自定义预设见 uno.config.ts通过变体 API 为 story 环境补充_hover模拟类可视为该机制在组件预览工作流中的延伸应用。九、在 airi monorepo 中的落地模式共享配置 按端覆盖观察本仓库可总结出把 presetWind3 用进大型 monorepo 的实用范式根级导出共享配置uno.config.ts 中sharedUnoConfig()聚合 presetWind3 及配套预设/transformer、扩展 rules、safelist 与自定义主题含上述动画、字体族。子应用用mergeConfigs叠加apps/stage-pocket/uno.config.ts 将共享配置与presetWebFonts、安全区safe-area自定义 rules、px-safe/py-safeshortcuts 合并得到移动端专属能力。扫描范围按需收窄内容站的 docs/uno.config.ts 将提取范围限定在.vitepress/**与content/**/*.md根配置则通过 content.pipeline.include/exclude 决定是否纳入js/ts源文件默认只提取.vue/.svelte/.tsx/.md/.html等并显式排除node_modules。这正是官方 skill 反复提醒的先看配置、再决定类名写在哪里的原因。十、延伸阅读presetWind3 常与本仓库/官方文档中的以下内容配合理解更现代的姊妹预设preset-wind4面向 Tailwind CSS v4 与现代 CSS 特性轻量底子preset-mini自定义构建时的最小化预设配套预设attributify、typography、web-fonts、icons参见 SKILL.md 预设索引引擎机制规则、变体、主题、提取与 safelist 分别见 core-rules、core-variants、core-theme、core-extracting、core-safelist工程集成Vite 集成指南 与 Nuxt 集成指南综上presetWind3 是 airi 全端样式体系的通用语向下兼容 Tailwind v3 / Windi 的既有心智与存量代码向上通过暗色策略、任意值语法、扩展动画主题与共享配置合并支撑起横跨 Web、桌面与移动端的一致 UI 基座。若你的新项目正在 UnoCSS 的预设选择上犹豫presetWind3 就是最稳妥的默认答案。【免费下载链接】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),仅供参考
返回列表