完全指南:顏色、斷點與設(shè)計令牌(Airi 項目實戰(zhàn)解析))
UnoCSS 主題系統(tǒng)完全指南顏色、斷點與設(shè)計令牌Airi 項目實戰(zhàn)解析【免費下載鏈接】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 的theme配置是一套與 Tailwind CSS / Windi CSS 一脈相承的設(shè)計令牌Design Tokens系統(tǒng)負(fù)責(zé)統(tǒng)一管理顏色、斷點、字體、動畫等全局樣式變量并深度融入 rules、variants、shortcuts 三大核心機制。本文以官方 skill 文檔 core-theme.md 為骨架結(jié)合 Airi 倉庫根目錄真實的 uno.config.ts 與各應(yīng)用子配置完整講解主題的配置方法、合并語義、斷點陷阱與多 preset 差異讀完即可在自己的 Vue / Vite 項目中搭建出可維護的主題體系。主題的本質(zhì)與默認(rèn)主題深度合并UnoCSS 的主題機制與 Tailwind / Windi 類似配置中的theme對象會與默認(rèn)主題做深度合并deep merge因此你無需重復(fù)聲明全部默認(rèn)值只需覆蓋關(guān)心的部分。核心入口是一個 uno.config.ts 配置文件UnoCSS 會自動在項目根目錄查找uno.config.{js,ts,mjs,mts}或unocss.config.{js,ts,mjs,mts}見 core-config.md。最基本的顏色主題用法如下theme: { colors: { veryCool: #0000ff, // classtext-very-cool brand: { primary: hsl(var(--hue, 217) 78% 51%), // classbg-brand-primary DEFAULT: #942192, // classbg-brand }, }, }這里揭示了兩個關(guān)鍵約定葉子節(jié)點如veryCool: #0000ff直接映射為工具類后綴text-very-cool、bg-very-cool立即可用嵌套對象如brand通過路徑訪問子鍵同時DEFAULT鍵用于生成不帶后綴的bg-brand類。顏色值不僅支持十六進制還可以直接使用 CSS 變量表達式如hsl(var(--hue, 217) 78% 51%)這為運行時動態(tài)換膚例如根據(jù)用戶偏好切換主色相保留了通道。在 rules 中讀取主題動態(tài)規(guī)則的心臟主題的真正價值在于被規(guī)則消費。動態(tài)規(guī)則dynamic rules的函數(shù)簽名第二參數(shù)為上下文對象其中包含themerules: [ [/^text-(.*)$/, ([, c], { theme }) { if (theme.colors[c]) return { color: theme.colors[c] } }], ]這種「正則匹配類名 查表主題」的模式正是 UnoCSS 工具類體系的底層范式。Airi 倉庫在 uno.config.ts 中有一個實戰(zhàn)范例bg-dotted-[...]規(guī)則它通過parseColor解析主題顏色并生成徑向漸變點陣背景[/^bg-dotted-\[(.*)\]$/, ([, color], { theme }) { const parsedColor parseColor(color, theme) return { background-image: radial-gradient(circle at 1px 1px, ${colorToString(parsedColor?.cssColor ?? parsedColor?.color ?? color, var(--un-background-opacity))} 1px, transparent 0), --un-background-opacity: parsedColor?.cssColor?.alpha ?? parsedColor?.alpha ?? 1, } }],可以看到parseColor(color, theme)同時接受主題鍵如primary與任意 CSS 顏色值這正是主題作為「共享色板」在規(guī)則層被復(fù)用的直接證據(jù)。規(guī)則層更多語法靜態(tài)規(guī)則、特殊符號、多選擇器規(guī)則等可參考 core-rules.md。在 variants 中讀取主題響應(yīng)式與偽類的數(shù)據(jù)源變體variants同樣可以在match函數(shù)中拿到theme常用于讀取theme.breakpoints、theme.colors來實現(xiàn)自定義響應(yīng)式前綴variants: [ { name: variant-name, match(matcher, { theme }) { // Access theme.breakpoints, theme.colors, etc. }, }, ]變體的工作方式是「逐級剝前綴」hover:m-2被hover:變體匹配后剝離為m-2再交給規(guī)則生成.m-2最后變體將選擇器改寫為.hover\:m-2:hover流程詳見 core-variants.md。Airi 的 uno.config.ts 中定義了一個讀取 matcher 的presetStoryMockHover預(yù)設(shè)通過改寫 selector 把:hover同時綁定到._hover類用于 Storybook 場景下模擬懸停態(tài)——這也是變體機制與主題/選擇器配合的典型工程實踐。在 shortcuts 中讀取主題動態(tài)快捷類的查表模式shortcuts 用于把多條工具類組合成語義化類名動態(tài) shortcuts 同樣接收帶theme的上下文shortcuts: [ [/^badge-(.*)$/, ([, c], { theme }) { if (Object.keys(theme.colors).includes(c)) return bg-${c}4:10 text-${c}5 rounded }], ]上例中bg-${c}4:10的寫法利用了 UnoCSS 的顏色透明度語法bg-primary-400/10風(fēng)格此處4為色階、10為透明度百分比即「主題色板 透明度修飾符」的組合。shortcuts 在構(gòu)建期展開、支持引用其他 shortcuts、且與所有變體兼容hover:btn、dark:btn均可用詳見 core-shortcuts.md。斷點配置覆蓋而非合并務(wù)必當(dāng)心斷點是響應(yīng)式設(shè)計的基石但 UnoCSS 的breakpoints有一個重要陷阱自定義breakpoints對象會整體覆蓋默認(rèn)值而不是合并。theme: { breakpoints: { sm: 320px, md: 640px, }, }配置后只有sm:和md:兩個變體可用默認(rèn)的lg、xl、2xl全部失效。同理verticalBreakpoints對縱向布局生效方式一致。繼承默認(rèn)斷點extendTheme 的正確姿勢若希望「在默認(rèn)斷點基礎(chǔ)上微調(diào)」必須使用extendTheme回調(diào)手工展開合并extendTheme: (theme) { return { ...theme, breakpoints: { ...theme.breakpoints, sm: 320px, md: 640px, }, } }斷點排序保持單位一致UnoCSS 會對斷點按數(shù)值大小排序以生成min-width/max-width媒體查詢?;煊脝挝粫?dǎo)致排序錯誤theme: { breakpoints: { sm: 320px, // Dont mix units - convert rem to px // md: 40rem, // Bad md: ${40 * 16}px, // Good lg: 960px, }, }${40 * 16}px即 640px用模板計算保持全部斷點統(tǒng)一為px避免排序異常。extendTheme修改或替換合并后的主題extendTheme在默認(rèn)主題與theme合并完成后執(zhí)行拿到的是最終主題對象支持兩種用法就地修改mutateextendTheme: (theme) { theme.colors.veryCool #0000ff theme.colors.brand { primary: hsl(var(--hue, 217) 78% 51%), } }返回新對象整體替換replaceextendTheme: (theme) { return { ...theme, colors: { ...theme.colors, veryCool: #0000ff, }, } }兩種方式各有用武之地mutate 適合在 preset 內(nèi)部增量注入令牌replace 適合需要過濾/重組鍵集的場景注意必須展開...theme以免丟失默認(rèn)令牌。從源碼結(jié)構(gòu)看這一機制也是 preset 向配置暴露主題擴展點的官方通道。不同 preset 的主題鍵差異wind3 與 wind4主題鍵在不同 preset 中命名存在差異遷移或混用前必須確認(rèn)。官方對照表如下主題鍵preset-wind3主題鍵preset-wind4fontFamilyfontfontSizetext.fontSizelineHeighttext.lineHeight或leadingletterSpacingtext.letterSpacing或trackingborderRadiusradiuseasingeasebreakpointsbreakpointboxShadowshadowtransitionPropertypropertywind3 是「Tailwind CSS v3 / Windi CSS 兼容」的常用預(yù)設(shè)unocss/preset-uno與unocss/preset-wind已廢棄并改名為unocss/preset-wind3wind4 面向 Tailwind v4 風(fēng)格引入了text.fontSize等嵌套結(jié)構(gòu)與 CSS 變量主題層。若需要極簡底座可選用 preset-mini.md其theme內(nèi)的breakpoints同樣是覆蓋而非合并語義。常見主題鍵一覽colors— 調(diào)色板支持嵌套對象與DEFAULT鍵breakpoints— 響應(yīng)式斷點覆蓋語義verticalBreakpoints對應(yīng)縱向布局fontFamily— 字體棧fontSize— 字號刻度spacing— 間距刻度borderRadius— 圓角值boxShadow— 陰影定義animation— 動畫關(guān)鍵幀與時長Airi 倉庫實戰(zhàn)一套貫穿全倉的主題配置Airi 是一個 monorepo根目錄 uno.config.ts 通過sharedUnoConfig()導(dǎo)出共享配置各應(yīng)用再以mergeConfigs疊加差異。這套配置是主題系統(tǒng)的絕佳范本。字體族主題多層回退的 fontFamilytheme: { fontFamily: { sans: DM Sans Variant, DM Sans, ui-sans-serif, system-ui, sans-serif, ..., sans-rounded: Comfortaa Variable, Comfortaa, DM Sans, ..., cute: Nunito Variable, Nunito, ChillRoundM, Kiwi Maru, Comfortaa Variable, ..., cutejp: Nunito Variable, Nunito, ChillRoundM, Kiwi Maru, ..., cuteen: Nunito Variable, Nunito, ChillRoundM, Kiwi Maru, ..., }, }見 uno.config.ts這里sans、sans-rounded、cute、cutejp、cuteen組成了面向不同語氣可愛/日文/英文的字體令牌配合 packages/font-* 系列自托管字體包如font-chillroundm、font-cjkfonts-allseto、font-xiaolai實現(xiàn)「CSS 變量 多層回退」的字體主題。值得留意的是根配置同時通過presetWebFontsFonts(fontsource | none)在 apps/stage-web/uno.config.ts 中按構(gòu)建環(huán)境切換字體 provider。animation 主題關(guān)鍵幀 時長 緩動三段式animation: { keyframes: { overlayShow: {from{opacity:0;}to{opacity:1;}}, contentShow: {from:{opacity:0;transform:translate(-50%,-48%) scale(0.96);}to:{opacity:1;transform:translate(-50%,-50%) scale(1);}}, slideUpAndFade: {from{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}, // ... }, durations: { overlayShow: 300ms, contentShow: 150ms, slideUpAndFade: 400ms, }, timingFns: { overlayShow: cubic-bezier(0.16, 1, 0.3, 1), fadeIn: ease-in-out, }, }見 uno.config.ts這套 keyframes / durations / timingFns 結(jié)構(gòu)與官方 wind4 的theme/animate.ts對齊覆蓋了彈層overlay/content、滑入滑出slideXxxAndFade、淡入淡出fadeIn/fadeOut等 UI 過渡是「以主題令牌驅(qū)動動畫」的最佳實踐。預(yù)設(shè)注入的主題色板presetChromaticAiri 通過presetChromatic預(yù)設(shè)動態(tài)生成主題色階presetChromatic({ baseHue: 220.44, colors: { primary: 0, complementary: 180, }, }) as Preset,見 uno.config.ts它基于色相基準(zhǔn)baseHue: 220.44自動推導(dǎo)出primary同相與complementary補色 180°的完整色階。與之配套的safelistAllPrimaryBackgrounds()uno.config.ts會把bg-primary及 50–950 各色階、5–100 各透明度的組合全部寫入safelist確保動態(tài)拼接的類名不會被按需提取漏掉[undefined, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950].map((shade) { const prefix shade ? bg-primary-${shade} : bg-primary return [prefix, ...[5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100].map(opacity ${prefix}/${opacity})] }).flat()這正是「主題色板 safelist」在真實大型應(yīng)用中的典型配合主題負(fù)責(zé)語義化顏色safelist 保證運行時拼接的類名穩(wěn)定產(chǎn)出。子應(yīng)用覆蓋mergeConfigs 按需擴展apps/stage-web/uno.config.ts 通過mergeConfigs([sharedUnoConfig(), {...}])在共享主題之上追加presetWebFonts并顯式配置timeouts.warning/failure規(guī)避 CI 網(wǎng)絡(luò)超時與transition-colors-none等專屬規(guī)則。這種「根配置定主題基調(diào) 子應(yīng)用按需覆蓋」的分層模式使整個 monorepo 的顏色、字體、動畫令牌保持單一事實來源。小結(jié)UnoCSS 主題系統(tǒng)的核心可以歸納為四句話theme與默認(rèn)主題深度合并breakpoints覆蓋不合并想繼承就用extendTheme展開rules / variants / shortcuts 都能通過上下文{ theme }消費令牌不同 preset 的主題鍵命名不同wind3 與 wind4 需對照遷移。Airi 倉庫的 uno.config.ts 為這三者提供了完整的工業(yè)化范例——從多字體回退、動畫三段式令牌到預(yù)設(shè)動態(tài)色階與 safelist 聯(lián)動值得作為你搭建自己主題系統(tǒng)的直接參考。如果你想進一步深入建議按此順序閱讀官方 skill 文檔core-config.md配置項全覽、core-rules.md規(guī)則消費主題、core-shortcuts.md快捷類消費主題、core-variants.md變體消費主題再對照 preset-wind3.md 與 preset-mini.md 理解主題鍵在預(yù)設(shè)間的差異。【免費下載鏈接】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創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考