├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .prettierrc ├── .vitepress ├── config.ts ├── content.ts ├── contributors.ts └── theme │ ├── components │ ├── ContentExamples.vue │ ├── ContentIntegrations.vue │ ├── HomePage.vue │ └── LinkGrid.vue │ ├── index.ts │ ├── overrides.css │ ├── rainbow.css │ ├── useComponents.ts │ └── vars.css ├── LICENSE ├── README.md ├── about └── index.md ├── config ├── autocomplete.md ├── extractors.md ├── index.md ├── layers.md ├── preflights.md ├── presets.md ├── rules.md ├── shortcuts.md ├── theme.md ├── transformers.md └── variants.md ├── extractors ├── arbitrary-variants.md ├── pug.md └── svelte.md ├── guide ├── config-file.md ├── extracting.md ├── index.md ├── packages.md ├── presets.md ├── style-reset.md └── why.md ├── index.md ├── integrations ├── astro.md ├── cli.md ├── eslint.md ├── index.md ├── jetbrains.md ├── next.md ├── nuxt.md ├── postcss.md ├── runtime.md ├── svelte-scoped.md ├── vite.md ├── vscode.md └── webpack.md ├── package.json ├── pnpm-lock.yaml ├── presets ├── attributify.md ├── community.md ├── icons.md ├── index.md ├── mini.md ├── rem-to-px.md ├── tagify.md ├── typography.md ├── uno.md ├── web-fonts.md └── wind.md ├── public ├── WeChat.png ├── favicon.ico ├── favicon.svg ├── google5e5d9f9fc6107357.html ├── logo.svg ├── og.png ├── robots.txt └── search.xml ├── tools ├── autocomplete.md ├── core.md └── inspector.md ├── transformers ├── attributify-jsx.md ├── compile-class.md ├── directives.md └── variant-group.md ├── tsconfig.json ├── unocss.config.ts └── vite.config.ts /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Deploy To Github pages 2 | on: 3 | push: 4 | branches: 5 | - main 6 | jobs: 7 | build-and-deploy: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v3 12 | with: 13 | persist-credentials: false 14 | - name: Install pnpm 15 | uses: pnpm/action-setup@v2 16 | with: 17 | version: 6.x 18 | - name: Use Node.js 19 | uses: actions/setup-node@v3 20 | with: 21 | node-version: 16.x 22 | registry-url: https://registry.npmjs.org/ 23 | cache: pnpm 24 | - name: Install and Build 25 | run: | 26 | pnpm install 27 | pnpm build 28 | - name: Deploy 29 | uses: JamesIves/github-pages-deploy-action@v4.2.2 30 | with: 31 | branch: gh-pages 32 | folder: ./dist 33 | 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | .nuxt 4 | .temp 5 | *.log 6 | components.d.ts 7 | dist 8 | index.json 9 | indexes.json 10 | node_modules 11 | cache 12 | packages/*/LICENSE 13 | packages/contributing.md 14 | packages/core/README.md 15 | packages/public/badge-* 16 | packages/*/index.mjs 17 | playgrounds/*/pnpm-lock.yaml 18 | types 19 | coverage 20 | .eslintcache 21 | .vitepress/cache 22 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "javascript.format.insertSpaceBeforeFunctionParenthesis": true, 5 | "vetur.format.defaultFormatter.js": "vscode-typescript", 6 | "eslintIntegration": true, 7 | "htmlWhitespaceSensitivity": "ignore", 8 | "trailingComma": "none", 9 | "arrowParens": "avoid" 10 | } 11 | -------------------------------------------------------------------------------- /.vitepress/config.ts: -------------------------------------------------------------------------------- 1 | import { createWriteStream } from 'fs' 2 | import { resolve } from 'path' 3 | import { defineConfig } from 'vitepress' 4 | import type { DefaultTheme } from 'vitepress/types' 5 | import { SitemapStream } from 'sitemap' 6 | // @ts-ignore 7 | import { version } from '../package.json' 8 | 9 | const ogUrl = 'https://unocss.dev/' 10 | const ogImage = `${ogUrl}og.png` 11 | const title = 'UnoCSS' 12 | const description = 'unocss 中文文档' 13 | const links = [] 14 | const Guides: DefaultTheme.NavItemWithLink[] = [ 15 | { text: '开始使用', link: '/guide/' }, 16 | { text: '为什么是 UnoCSS?', link: '/guide/why' }, 17 | { text: '预设', link: '/guide/presets' }, 18 | { text: '样式重置', link: '/guide/style-reset' }, 19 | { text: '配置文件', link: '/guide/config-file' }, 20 | { text: '提取和安全列表', link: '/guide/extracting' }, 21 | { text: '包', link: '/guide/packages' } 22 | ] 23 | 24 | const Configs: DefaultTheme.NavItemWithLink[] = [ 25 | { text: '概述', link: '/config/' }, 26 | { text: '规则', link: '/config/rules' }, 27 | { text: '快捷方式', link: '/config/shortcuts' }, 28 | { text: '主题', link: '/config/theme' }, 29 | { text: '变体', link: '/config/variants' }, 30 | { text: '提取器', link: '/config/extractors' }, 31 | { text: '转换器', link: '/config/transformers' }, 32 | { text: '预检查', link: '/config/preflights' }, 33 | { text: '图层', link: '/config/layers' }, 34 | { text: '自动完成', link: '/config/autocomplete' }, 35 | { text: '预设', link: '/config/presets' } 36 | ] 37 | 38 | const Integrations: DefaultTheme.NavItemWithLink[] = [ 39 | { text: 'Vite', link: '/integrations/vite' }, 40 | { text: 'Nuxt', link: '/integrations/nuxt' }, 41 | { text: 'Astro', link: '/integrations/astro' }, 42 | { text: 'Svelte Scoped', link: '/integrations/svelte-scoped' }, 43 | { text: 'Webpack', link: '/integrations/webpack' }, 44 | { text: 'Runtime', link: '/integrations/runtime' }, 45 | { text: 'CLI', link: '/integrations/cli' }, 46 | { text: 'PostCSS', link: '/integrations/postcss' }, 47 | { text: 'ESLint', link: '/integrations/eslint' }, 48 | { text: 'VSCode extension', link: '/integrations/vscode' }, 49 | { text: 'JetBrains IDE Plugin', link: '/integrations/jetbrains' } 50 | ] 51 | 52 | const Presets: DefaultTheme.NavItemWithLink[] = [ 53 | { text: 'Uno (默认)', link: '/presets/uno' }, 54 | { text: '图标', link: '/presets/icons' }, 55 | { text: '属性化', link: '/presets/attributify' }, 56 | { text: '排版', link: '/presets/typography' }, 57 | { text: 'Web 字体', link: '/presets/web-fonts' }, 58 | { text: 'Wind', link: '/presets/wind' }, 59 | { text: 'Mini', link: '/presets/mini' }, 60 | { text: '标签化', link: '/presets/tagify' }, 61 | { text: 'Rem to px', link: '/presets/rem-to-px' } 62 | ] 63 | 64 | const Transformers: DefaultTheme.NavItemWithLink[] = [ 65 | { text: '转换组', link: '/transformers/variant-group' }, 66 | { text: '指令', link: '/transformers/directives' }, 67 | { text: '编译类', link: '/transformers/compile-class' }, 68 | { text: 'JSX 属性化', link: '/transformers/attributify-jsx' } 69 | ] 70 | 71 | const Extractors: DefaultTheme.NavItemWithLink[] = [ 72 | { text: 'Pug 提取器', link: '/extractors/pug' } 73 | // { text: 'Svelte extractor', link: '/extractors/svelte' }, 74 | ] 75 | 76 | const Tools: DefaultTheme.NavItemWithLink[] = [ 77 | { text: '检查器', link: '/tools/inspector' }, 78 | { text: '核心', link: '/tools/core' }, 79 | { text: '自动完成', link: '/tools/autocomplete' } 80 | ] 81 | 82 | const Nav: DefaultTheme.NavItem[] = [ 83 | { 84 | text: '指南', 85 | items: [ 86 | { 87 | text: '指南', 88 | items: Guides 89 | } 90 | ] 91 | }, 92 | { 93 | text: '集成', 94 | items: [ 95 | { 96 | text: '概述', 97 | link: '/integrations/' 98 | }, 99 | { 100 | text: '集成', 101 | items: Integrations 102 | }, 103 | { 104 | text: '示例', 105 | link: 'https://github.com/unocss/unocss/tree/main/examples' 106 | } 107 | ] 108 | }, 109 | { 110 | text: '配置', 111 | items: [ 112 | { 113 | text: '配置文件', 114 | link: '/guide/config-file' 115 | }, 116 | { 117 | text: 'Concepts', 118 | items: Configs 119 | } 120 | ] 121 | }, 122 | { 123 | text: '预设', 124 | items: [ 125 | { 126 | text: '概述', 127 | link: '/presets/' 128 | }, 129 | { 130 | text: '社区预设', 131 | link: '/presets/community' 132 | }, 133 | { 134 | text: '预设', 135 | items: Presets 136 | }, 137 | { 138 | text: '转换器', 139 | items: Transformers 140 | }, 141 | { 142 | text: '转换器', 143 | items: Extractors 144 | } 145 | ] 146 | }, 147 | { 148 | text: '关于本站', 149 | link: '/about/' 150 | }, 151 | { text: '交互式文档', link: `${ogUrl}interactive/`, target: '_blank' }, 152 | { text: '演练场', link: `${ogUrl}play/`, target: '_blank' }, 153 | { 154 | text: `v${version}`, 155 | items: [ 156 | { 157 | text: '发行说明', 158 | link: 'https://github.com/unocss/unocss/releases' 159 | }, 160 | { 161 | text: '贡献', 162 | link: 'https://github.com/unocss/unocss/blob/main/CONTRIBUTING.md' 163 | } 164 | ] 165 | } 166 | ] 167 | 168 | const SidebarGuide: DefaultTheme.SidebarItem[] = [ 169 | { 170 | text: '指南', 171 | items: Guides 172 | }, 173 | { 174 | text: '集成', 175 | items: [ 176 | { 177 | text: '概述', 178 | link: '/integrations/' 179 | }, 180 | ...Integrations, 181 | { 182 | text: '示例', 183 | link: '/integrations/#示例' 184 | } 185 | ] 186 | }, 187 | { 188 | text: 'Presets', 189 | link: '/presets/' 190 | }, 191 | { 192 | text: '配置', 193 | link: '/config/' 194 | }, 195 | { 196 | text: '示例', 197 | link: 'https://github.com/unocss/unocss/tree/main/examples' 198 | } 199 | ] 200 | 201 | const SidebarPresets: DefaultTheme.SidebarItem[] = [ 202 | { 203 | text: '概述', 204 | link: '/presets/' 205 | }, 206 | { 207 | text: '预设', 208 | collapsed: false, 209 | items: Presets 210 | }, 211 | { 212 | text: '社区预设', 213 | link: '/presets/community' 214 | }, 215 | { 216 | text: '转换器', 217 | collapsed: false, 218 | items: Transformers 219 | }, 220 | { 221 | text: '提取器', 222 | collapsed: false, 223 | items: Extractors 224 | }, 225 | { 226 | text: '第三方包', 227 | collapsed: false, 228 | items: Tools 229 | } 230 | ] 231 | 232 | const SidebarConfig: DefaultTheme.SidebarItem[] = [ 233 | { 234 | text: '配置', 235 | collapsed: false, 236 | items: Configs 237 | }, 238 | { 239 | text: '配置文件', 240 | link: '/guide/config-file' 241 | } 242 | ] 243 | const GITHUB_URL = '/unocss-docs-cn/' 244 | export default defineConfig({ 245 | lang: 'zh-CN', 246 | title, 247 | base: GITHUB_URL, 248 | titleTemplate: title, 249 | description, 250 | outDir: './dist', 251 | locales: { 252 | root: { 253 | label: '简体中文', 254 | lang: 'zh', 255 | head: [ 256 | [ 257 | 'meta', 258 | { 259 | 'http-equiv': 'refresh', 260 | content: '0; url=https://unocss-cn.pages.dev/' 261 | } 262 | ] 263 | ], 264 | }, 265 | en: { 266 | label: 'English', 267 | lang: 'en', 268 | link: 'https://unocss.dev/' 269 | } 270 | }, 271 | head: [ 272 | [ 273 | 'link', 274 | { rel: 'icon', href: `${GITHUB_URL}favicon.svg`, type: 'image/svg+xml' } 275 | ], 276 | [ 277 | 'link', 278 | { 279 | rel: 'alternate icon', 280 | href: `${GITHUB_URL}favicon.ico`, 281 | type: 'image/png', 282 | sizes: '16x16' 283 | } 284 | ], 285 | ['meta', { name: 'author', content: 'Anthony Fu' }], 286 | ['meta', { property: 'og:type', content: 'website' }], 287 | ['meta', { name: 'og:title', content: title }], 288 | ['meta', { name: 'og:description', content: description }], 289 | ['meta', { property: 'og:image', content: ogImage }], 290 | ['meta', { name: 'twitter:title', content: title }], 291 | ['meta', { name: 'twitter:card', content: 'summary_large_image' }], 292 | ['meta', { name: 'twitter:image', content: ogImage }], 293 | ['meta', { name: 'twitter:site', content: '@antfu7' }], 294 | ['meta', { name: 'twitter:url', content: ogUrl }], 295 | [ 296 | 'link', 297 | { 298 | rel: 'search', 299 | type: 'application/opensearchdescription+xml', 300 | href: '/search.xml', 301 | title: 'UnoCSS' 302 | } 303 | ] 304 | ], 305 | lastUpdated: true, 306 | cleanUrls: true, 307 | ignoreDeadLinks: [/^\/play/, /^\/interactive/, /:\/\/localhost/], 308 | 309 | markdown: { 310 | theme: { 311 | light: 'vitesse-light', 312 | dark: 'vitesse-dark' 313 | } 314 | }, 315 | 316 | themeConfig: { 317 | logo: '/logo.svg', 318 | nav: Nav, 319 | // @ts-ignore 320 | localeLinks: { 321 | text: '简体中文', 322 | items: [{ text: 'English', link: 'https://unocss.dev/' }] 323 | }, 324 | sidebar: { 325 | '/guide/': SidebarGuide, 326 | '/integrations/': SidebarGuide, 327 | '/about/': SidebarGuide, 328 | '/tools/': SidebarPresets, 329 | '/presets/': SidebarPresets, 330 | '/transformers/': SidebarPresets, 331 | '/extractors/': SidebarPresets, 332 | '/config/': SidebarConfig 333 | }, 334 | algolia: { 335 | appId: 'AXP9JFI96W', 336 | apiKey: '161aea93f115d66f8f0d8658af517c03', 337 | indexName: 'unocss--cn', 338 | placeholder: '请输入关键词', 339 | translations: { 340 | button: { 341 | buttonText: '搜索' 342 | } 343 | } 344 | }, 345 | editLink: { 346 | pattern: 'https://github.com/unocss/unocss/edit/main/docs/:path', 347 | text: '在 GitHub 上编辑此页' 348 | }, 349 | socialLinks: [ 350 | { icon: 'github', link: 'https://github.com/unocss/unocss' }, 351 | { icon: 'discord', link: 'https://chat.antfu.me' } 352 | ], 353 | footer: { 354 | message: 'Released under the MIT License.', 355 | copyright: 'Copyright © 2021-PRESENT Anthony Fu' 356 | } 357 | }, 358 | 359 | //region Generate sitemap 360 | transformHtml: (_, id, { pageData }) => { 361 | if (!/[\\/]404\.html$/.test(id)) { 362 | links.push({ 363 | // you might need to change this if not using clean urls mode 364 | url: pageData.relativePath.replace(/((^|\/)index)?\.md$/, '$2'), 365 | lastmod: pageData.lastUpdated 366 | }) 367 | } 368 | }, 369 | buildEnd: async ({ outDir }) => { 370 | const sitemap = new SitemapStream({ 371 | hostname: 'https://alfred-skyblue.github.io/unocss-docs-cn/' 372 | }) 373 | const writeStream = createWriteStream(resolve(outDir, 'sitemap.xml')) 374 | sitemap.pipe(writeStream) 375 | links.forEach(link => sitemap.write(link)) 376 | sitemap.end() 377 | // eslint-disable-next-line promise/param-names 378 | await new Promise(r => writeStream.on('finish', r)) 379 | } 380 | //endregion 381 | }) 382 | -------------------------------------------------------------------------------- /.vitepress/content.ts: -------------------------------------------------------------------------------- 1 | export interface Integration { 2 | icon: string 3 | name: string 4 | link: string 5 | target?: string 6 | secondary?: string 7 | } 8 | 9 | export interface Example { 10 | name: string 11 | path: string 12 | stackblitz?: boolean 13 | codesandbox?: boolean 14 | icon?: string 15 | icons?: string[] 16 | } 17 | 18 | // @unocss-include 19 | 20 | export const integrations: Integration[] = [ 21 | { name: 'Vite', link: '/integrations/vite', icon: 'i-logos-vitejs' }, 22 | { name: 'Nuxt', link: '/integrations/nuxt', icon: 'i-logos-nuxt-icon' }, 23 | { name: 'Astro', link: '/integrations/astro', icon: 'i-logos-astro-icon dark:invert' }, 24 | { name: 'Svelte', secondary: '(Scoped)', link: '/integrations/svelte-scoped', icon: 'i-logos-svelte-icon' }, 25 | { name: 'Webpack', link: '/integrations/webpack', icon: 'i-logos-webpack' }, 26 | { name: 'CDN Runtime', link: '/integrations/runtime', icon: 'i-logos-javascript' }, 27 | { name: 'CLI', link: '/integrations/cli', icon: 'i-carbon-terminal' }, 28 | { name: 'PostCSS', link: '/integrations/postcss', icon: 'i-logos-postcss' }, 29 | { name: 'ESLint', link: '/integrations/eslint', icon: 'i-logos-eslint' }, 30 | { name: 'VSCode', link: '/integrations/vscode', icon: 'i-logos-visual-studio-code' }, 31 | ] 32 | 33 | export const examples: Example[] = [ 34 | { 35 | name: 'astro', 36 | path: 'examples/astro', 37 | icon: 'i-logos-astro-icon dark:invert', 38 | stackblitz: true, 39 | }, 40 | { 41 | name: 'quasar', 42 | path: 'examples/quasar', 43 | icon: 'i-vscode-icons-file-type-quasar', 44 | stackblitz: true, 45 | }, 46 | { 47 | name: 'sveltekit-scoped', 48 | path: 'examples/sveltekit-scoped', 49 | icon: 'i-logos-svelte-icon', 50 | stackblitz: true, 51 | }, 52 | { 53 | name: 'vite-solid', 54 | path: 'examples/vite-solid', 55 | icon: 'i-logos-solidjs-icon', 56 | stackblitz: true, 57 | }, 58 | { 59 | name: 'vue-cli4', 60 | path: 'examples/vue-cli4', 61 | icon: 'i-logos-vue', 62 | stackblitz: true, 63 | }, 64 | { 65 | name: 'astro-vue', 66 | path: 'examples/astro-vue', 67 | icons: [ 68 | 'i-logos-astro-icon dark:invert', 69 | 'i-logos-vue', 70 | ], 71 | stackblitz: true, 72 | }, 73 | { 74 | name: 'qwik', 75 | path: 'examples/qwik', 76 | icon: 'i-logos-qwik-icon', 77 | // stackblitz: true, 78 | }, 79 | { 80 | name: 'vite-elm', 81 | path: 'examples/vite-elm', 82 | icon: 'i-logos-elm', 83 | // stackblitz: true, 84 | }, 85 | { 86 | name: 'vite-svelte', 87 | path: 'examples/vite-svelte', 88 | icons: [ 89 | 'i-logos-vitejs', 90 | 'i-logos-svelte-icon', 91 | ], 92 | stackblitz: true, 93 | }, 94 | { 95 | name: 'vue-cli5', 96 | path: 'examples/vue-cli5', 97 | icon: 'i-logos-vue', 98 | stackblitz: true, 99 | }, 100 | { 101 | name: 'next', 102 | path: 'examples/next', 103 | icon: 'i-logos-nextjs-icon', 104 | // stackblitz: true, 105 | codesandbox: true, 106 | }, 107 | { 108 | name: 'react', 109 | path: 'examples/react', 110 | icon: 'i-logos-react', 111 | stackblitz: true, 112 | }, 113 | { 114 | name: 'vite-lightningcss', 115 | path: 'examples/vite-lightningcss', 116 | icon: 'i-ph-lightning text-yellow', 117 | // lightingcss is not supported by stackblitz yet 118 | // stackblitz: true, 119 | }, 120 | { 121 | name: 'vite-lit', 122 | path: 'examples/vite-lit', 123 | icon: 'i-logos-lit-icon', 124 | stackblitz: true, 125 | }, 126 | { 127 | name: 'vite-svelte-postcss', 128 | path: 'examples/vite-svelte-postcss', 129 | icons: [ 130 | 'i-logos-postcss', 131 | 'i-logos-svelte-icon', 132 | ], 133 | stackblitz: true, 134 | }, 135 | { 136 | name: 'nuxt2', 137 | path: 'examples/nuxt2', 138 | icon: 'i-logos-nuxt-icon', 139 | stackblitz: true, 140 | }, 141 | { 142 | name: 'remix', 143 | path: 'examples/remix', 144 | icon: 'i-logos-remix-icon dark:invert', 145 | stackblitz: true, 146 | }, 147 | { 148 | name: 'vite-preact', 149 | path: 'examples/vite-preact', 150 | icon: 'i-logos-preact', 151 | stackblitz: true, 152 | }, 153 | { 154 | name: 'vite-vue3', 155 | path: 'examples/vite-vue3', 156 | icons: [ 157 | 'i-logos-vitejs', 158 | 'i-logos-vue', 159 | ], 160 | stackblitz: true, 161 | }, 162 | { 163 | name: 'nuxt2-webpack', 164 | path: 'examples/nuxt2-webpack', 165 | icons: [ 166 | 'i-logos-webpack', 167 | 'i-logos-nuxt-icon', 168 | ], 169 | stackblitz: true, 170 | }, 171 | { 172 | name: 'sveltekit', 173 | path: 'examples/sveltekit', 174 | icon: 'i-logos-svelte-icon', 175 | stackblitz: true, 176 | }, 177 | { 178 | name: 'vite-pug', 179 | path: 'examples/vite-pug', 180 | icon: 'i-logos-pug', 181 | stackblitz: true, 182 | }, 183 | { 184 | name: 'vite-vue3-postcss', 185 | path: 'examples/vite-vue3-postcss', 186 | icons: [ 187 | 'i-logos-postcss', 188 | 'i-logos-vue', 189 | ], 190 | stackblitz: true, 191 | }, 192 | { 193 | name: 'nuxt3', 194 | path: 'examples/nuxt3', 195 | icon: 'i-logos-nuxt-icon', 196 | stackblitz: true, 197 | }, 198 | { 199 | name: 'sveltekit-preprocess', 200 | path: 'examples/sveltekit-preprocess', 201 | icon: 'i-logos-svelte-icon', 202 | stackblitz: true, 203 | }, 204 | { 205 | name: 'vite-react', 206 | path: 'examples/vite-react', 207 | icons: [ 208 | 'i-logos-vitejs', 209 | 'i-logos-react', 210 | ], 211 | stackblitz: true, 212 | }, 213 | ] 214 | .sort((a, b) => a.name.localeCompare(b.name)) 215 | -------------------------------------------------------------------------------- /.vitepress/contributors.ts: -------------------------------------------------------------------------------- 1 | import type { DefaultTheme } from 'vitepress' 2 | 3 | export interface Contributor { 4 | name: string 5 | avatar: string 6 | } 7 | 8 | export interface CoreTeam extends Partial { 9 | avatar: string 10 | name: string 11 | // required to download avatars from GitHub 12 | github: string 13 | twitter?: string 14 | webtools?: string 15 | discord?: string 16 | youtube?: string 17 | sponsor?: string 18 | title?: string 19 | org?: string 20 | desc?: string 21 | } 22 | 23 | function createLinks(tm: CoreTeam): CoreTeam { 24 | tm.links = [{ icon: 'github', link: `https://github.com/${tm.github}` }] 25 | if (tm.webtools) 26 | tm.links.push({ 27 | icon: 'mastodon', 28 | link: `https://elk.zone/m.webtoo.ls/@${tm.webtools}` 29 | }) 30 | if (tm.discord) tm.links.push({ icon: 'discord', link: tm.discord }) 31 | if (tm.youtube) 32 | tm.links.push({ 33 | icon: 'youtube', 34 | link: `https://www.youtube.com/@${tm.youtube}` 35 | }) 36 | tm.links.push({ icon: 'twitter', link: `https://twitter.com/${tm.twitter}` }) 37 | return tm 38 | } 39 | 40 | const plainTeamMembers: CoreTeam[] = [ 41 | { 42 | avatar: 'https://github.com/antfu.png', 43 | name: 'Anthony Fu', 44 | github: 'antfu', 45 | webtools: 'antfu', 46 | youtube: 'antfu', 47 | discord: 'https://chat.antfu.me', 48 | twitter: 'antfu7', 49 | sponsor: 'https://github.com/sponsors/antfu', 50 | title: 'A fanatical open sourceror, working', 51 | org: 'NuxtLabs', 52 | orgLink: 'https://nuxtlabs.com/', 53 | desc: 'Core team member of Vite & Vue' 54 | }, 55 | { 56 | avatar: 'https://github.com/chu121su12.png', 57 | name: 'Saya', 58 | github: 'chu121su12', 59 | title: 'Programmer' 60 | }, 61 | { 62 | avatar: 'https://github.com/zyyv.png', 63 | name: 'Chris', 64 | github: 'zyyv', 65 | twitter: 'chris_zyyv', 66 | title: 'Regardless of the past, do not ask the future.' 67 | }, 68 | { 69 | avatar: 'https://github.com/sibbng.png', 70 | name: 'sibbng', 71 | github: 'sibbng', 72 | twitter: 'sibbng', 73 | title: 'Designer / Developer' 74 | }, 75 | { 76 | avatar: 'https://github.com/userquin.png', 77 | name: 'Joaquín Sánchez', 78 | github: 'userquin', 79 | webtools: 'userquin', 80 | twitter: 'userquin', 81 | title: 'A fullstack and android developer', 82 | desc: "Vite's fanatical follower" 83 | }, 84 | { 85 | avatar: 'https://github.com/QiroNT.png', 86 | name: 'Chino Moca', 87 | github: 'QiroNT', 88 | twitter: 'QiroNT', 89 | title: 'Balance & Tradeoff' 90 | }, 91 | { 92 | avatar: 'https://github.com/johannschopplich.png', 93 | name: 'Johann Schopplich', 94 | github: 'johannschopplich', 95 | title: 'Full Stack Developer', 96 | desc: 'Pharmacist prior to that' 97 | }, 98 | { 99 | avatar: 'https://github.com/ydcjeff.png', 100 | name: 'Jeff Yang', 101 | github: 'ydcjeff', 102 | twitter: 'ydcjeff' 103 | }, 104 | { 105 | avatar: 'https://github.com/sudongyuer.png', 106 | name: 'Tsuki Su', 107 | github: 'sudongyuer', 108 | twitter: 'sudongyuer', 109 | title: 'A zealous open sourceror & Full Stack Developer & Junior designer', 110 | desc: 'Previously worked at Tencent, now starting a business' 111 | } 112 | ] 113 | 114 | const teamMembers = plainTeamMembers.map(tm => createLinks(tm)) 115 | 116 | export { teamMembers } 117 | -------------------------------------------------------------------------------- /.vitepress/theme/components/ContentExamples.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 44 | 45 | 55 | -------------------------------------------------------------------------------- /.vitepress/theme/components/ContentIntegrations.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /.vitepress/theme/components/HomePage.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 40 | -------------------------------------------------------------------------------- /.vitepress/theme/components/LinkGrid.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 23 | 24 | 38 | -------------------------------------------------------------------------------- /.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | // https://vitepress.dev/guide/custom-theme 2 | import { h, watch } from 'vue' 3 | import Theme from 'vitepress/theme' 4 | import './rainbow.css' 5 | import './vars.css' 6 | import './overrides.css' 7 | import 'uno.css' 8 | 9 | import HomePage from './components/HomePage.vue' 10 | import { useComponents } from './useComponents' 11 | 12 | let homePageStyle: HTMLStyleElement | undefined 13 | 14 | export default { 15 | ...Theme, 16 | Layout: () => { 17 | return h(Theme.Layout, null, { 18 | 'home-features-after': () => h(HomePage) 19 | }) 20 | }, 21 | enhanceApp({ router, app }) { 22 | if (typeof window === 'undefined') return 23 | useComponents(app) 24 | watch( 25 | () => router.route.data.relativePath, 26 | () => updateHomePageStyle(location.pathname === '/'), 27 | { immediate: true } 28 | ) 29 | } 30 | } 31 | 32 | if (typeof window !== 'undefined') { 33 | // detect browser, add to class for conditional styling 34 | const browser = navigator.userAgent.toLowerCase() 35 | if (browser.includes('chrome')) 36 | document.documentElement.classList.add('browser-chrome') 37 | else if (browser.includes('firefox')) 38 | document.documentElement.classList.add('browser-firefox') 39 | else if (browser.includes('safari')) 40 | document.documentElement.classList.add('browser-safari') 41 | } 42 | 43 | // Speed up the rainbow animation on home page 44 | function updateHomePageStyle(value: boolean) { 45 | if (value) { 46 | if (homePageStyle) return 47 | 48 | homePageStyle = document.createElement('style') 49 | homePageStyle.innerHTML = ` 50 | :root { 51 | animation: rainbow 12s linear infinite; 52 | }` 53 | document.body.appendChild(homePageStyle) 54 | } else { 55 | if (!homePageStyle) return 56 | 57 | homePageStyle.remove() 58 | homePageStyle = undefined 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /.vitepress/theme/overrides.css: -------------------------------------------------------------------------------- 1 | .vp-code-group .tabs label { 2 | background-color: transparent; 3 | } 4 | 5 | table { 6 | width: 100% !important; 7 | display: table; 8 | } 9 | 10 | .custom-block.tip .custom-block-title { 11 | color: var(--vp-c-brand); 12 | } 13 | 14 | .VPHero .image-bg { 15 | z-index: 1; 16 | opacity: 0.8; 17 | transition: opacity 1s ease; 18 | } 19 | 20 | .VPHero .image-container:hover .image-bg { 21 | opacity: 0.2; 22 | } 23 | 24 | 25 | /** 26 | * VitePress: Custom fix 27 | * -------------------------------------------------------------------------- */ 28 | 29 | /* 30 | Use lighter colors for links in dark mode for a11y. 31 | Also specify some classes twice to have higher specificity 32 | over scoped class data attribute. 33 | */ 34 | .dark .vp-doc a, 35 | .dark .vp-doc a > code, 36 | .dark .VPNavBarMenuLink.VPNavBarMenuLink:hover, 37 | .dark .VPNavBarMenuLink.VPNavBarMenuLink.active, 38 | .dark .link.link:hover, 39 | .dark .link.link.active, 40 | .dark .edit-link-button.edit-link-button, 41 | .dark .pager-link .title { 42 | color: var(--vp-c-brand-lighter); 43 | } 44 | 45 | .dark .vp-doc a:hover, 46 | .dark .vp-doc a > code:hover { 47 | color: var(--vp-c-brand-lightest); 48 | opacity: 1; 49 | } 50 | 51 | /* Transition by color instead of opacity */ 52 | .dark .vp-doc .custom-block a { 53 | transition: color 0.25s; 54 | } 55 | 56 | 57 | /* VitePress Search */ 58 | .VPLocalSearchBox .result { 59 | --vp-c-bg-search-result: var(--vp-c-bg); 60 | background: var(--vp-c-bg-search-result) !important; 61 | padding: 4px !important; 62 | border: 1px solid var(--vp-c-divider) !important; 63 | } 64 | .VPLocalSearchBox .result.selected { 65 | --vp-c-bg-search-result: var(--vp-c-bg-soft) !important; 66 | } 67 | .VPLocalSearchBox .result .excerpt-gradient-top { 68 | background: linear-gradient(var(--vp-c-bg-search-result),transparent) !important; 69 | } 70 | .VPLocalSearchBox .result .excerpt-gradient-bottom { 71 | background: linear-gradient(transparent,var(--vp-c-bg-search-result)) !important; 72 | } 73 | .VPLocalSearchBox .title-icon { 74 | display: none; 75 | } 76 | .VPLocalSearchBox .excerpt-wrapper { 77 | margin-top: 4px; 78 | } 79 | -------------------------------------------------------------------------------- /.vitepress/theme/rainbow.css: -------------------------------------------------------------------------------- 1 | @keyframes rainbow { 2 | 0% { --vp-c-brand: #00a98e; --vp-c-brand-light: #4ad1b4; --vp-c-brand-lighter: #78fadc; --vp-c-brand-dark: #008269; --vp-c-brand-darker: #005d47; --vp-c-brand-next: #009ff7; } 3 | 1.25% { --vp-c-brand: #00a996; --vp-c-brand-light: #4bd1bd; --vp-c-brand-lighter: #79fbe5; --vp-c-brand-dark: #008371; --vp-c-brand-darker: #005e4f; --vp-c-brand-next: #009dfa; } 4 | 2.5% { --vp-c-brand: #00a99f; --vp-c-brand-light: #4cd1c6; --vp-c-brand-lighter: #7afbee; --vp-c-brand-dark: #00837a; --vp-c-brand-darker: #005e56; --vp-c-brand-next: #009bfc; } 5 | 3.75% { --vp-c-brand: #00a9a7; --vp-c-brand-light: #4dd1cf; --vp-c-brand-lighter: #7bfbf8; --vp-c-brand-dark: #008382; --vp-c-brand-darker: #005e5e; --vp-c-brand-next: #0098fd; } 6 | 5% { --vp-c-brand: #00a9b0; --vp-c-brand-light: #4ed1d7; --vp-c-brand-lighter: #7dfaff; --vp-c-brand-dark: #00838a; --vp-c-brand-darker: #005e65; --vp-c-brand-next: #0096fd; } 7 | 6.25% { --vp-c-brand: #00a9b8; --vp-c-brand-light: #4fd1e0; --vp-c-brand-lighter: #7efaff; --vp-c-brand-dark: #008391; --vp-c-brand-darker: #005e6d; --vp-c-brand-next: #0093fd; } 8 | 7.5% { --vp-c-brand: #00a9c0; --vp-c-brand-light: #50d0e8; --vp-c-brand-lighter: #7ffaff; --vp-c-brand-dark: #008399; --vp-c-brand-darker: #005e74; --vp-c-brand-next: #2e90fc; } 9 | 8.75% { --vp-c-brand: #00a8c7; --vp-c-brand-light: #51d0f0; --vp-c-brand-lighter: #81f9ff; --vp-c-brand-dark: #0082a0; --vp-c-brand-darker: #005e7b; --vp-c-brand-next: #4d8dfa; } 10 | 10% { --vp-c-brand: #00a8cf; --vp-c-brand-light: #52cff7; --vp-c-brand-lighter: #82f8ff; --vp-c-brand-dark: #0082a7; --vp-c-brand-darker: #005e81; --vp-c-brand-next: #638af8; } 11 | 11.25% { --vp-c-brand: #00a7d5; --vp-c-brand-light: #53cfff; --vp-c-brand-lighter: #84f8ff; --vp-c-brand-dark: #0081ae; --vp-c-brand-darker: #005d87; --vp-c-brand-next: #7587f5; } 12 | 12.5% { --vp-c-brand: #00a6dc; --vp-c-brand-light: #55ceff; --vp-c-brand-lighter: #85f7ff; --vp-c-brand-dark: #0081b4; --vp-c-brand-darker: #005d8d; --vp-c-brand-next: #8583f1; } 13 | 13.75% { --vp-c-brand: #00a6e2; --vp-c-brand-light: #56cdff; --vp-c-brand-lighter: #87f6ff; --vp-c-brand-dark: #0080b9; --vp-c-brand-darker: #005c93; --vp-c-brand-next: #9280ed; } 14 | 15% { --vp-c-brand: #00a4e7; --vp-c-brand-light: #57ccff; --vp-c-brand-lighter: #88f4ff; --vp-c-brand-dark: #007fbf; --vp-c-brand-darker: #005b98; --vp-c-brand-next: #9f7ce9; } 15 | 16.25% { --vp-c-brand: #00a3ec; --vp-c-brand-light: #58caff; --vp-c-brand-lighter: #89f3ff; --vp-c-brand-dark: #007ec3; --vp-c-brand-darker: #005b9c; --vp-c-brand-next: #aa78e3; } 16 | 17.5% { --vp-c-brand: #00a2f1; --vp-c-brand-light: #58c9ff; --vp-c-brand-lighter: #8af1ff; --vp-c-brand-dark: #007dc8; --vp-c-brand-darker: #0059a0; --vp-c-brand-next: #b574dd; } 17 | 18.75% { --vp-c-brand: #00a0f4; --vp-c-brand-light: #59c7ff; --vp-c-brand-lighter: #8bf0ff; --vp-c-brand-dark: #007bcb; --vp-c-brand-darker: #0058a3; --vp-c-brand-next: #be71d7; } 18 | 20% { --vp-c-brand: #009ff7; --vp-c-brand-light: #5ac5ff; --vp-c-brand-lighter: #8ceeff; --vp-c-brand-dark: #007ace; --vp-c-brand-darker: #0057a6; --vp-c-brand-next: #c76dd1; } 19 | 21.25% { --vp-c-brand: #009dfa; --vp-c-brand-light: #5ac3ff; --vp-c-brand-lighter: #8decff; --vp-c-brand-dark: #0078d0; --vp-c-brand-darker: #0055a8; --vp-c-brand-next: #cf69c9; } 20 | 22.5% { --vp-c-brand: #009bfc; --vp-c-brand-light: #5bc1ff; --vp-c-brand-lighter: #8de9ff; --vp-c-brand-dark: #0076d2; --vp-c-brand-darker: #0053aa; --vp-c-brand-next: #d566c2; } 21 | 23.75% { --vp-c-brand: #0098fd; --vp-c-brand-light: #5bbfff; --vp-c-brand-lighter: #8ee7ff; --vp-c-brand-dark: #0074d3; --vp-c-brand-darker: #0051ab; --vp-c-brand-next: #dc63ba; } 22 | 25% { --vp-c-brand: #0096fd; --vp-c-brand-light: #5bbcff; --vp-c-brand-lighter: #8ee4ff; --vp-c-brand-dark: #0071d4; --vp-c-brand-darker: #004fab; --vp-c-brand-next: #e160b3; } 23 | 26.25% { --vp-c-brand: #0093fd; --vp-c-brand-light: #5bb9ff; --vp-c-brand-lighter: #8ee1ff; --vp-c-brand-dark: #006fd3; --vp-c-brand-darker: #004dab; --vp-c-brand-next: #e65eab; } 24 | 27.5% { --vp-c-brand: #2e90fc; --vp-c-brand-light: #69b6ff; --vp-c-brand-lighter: #99deff; --vp-c-brand-dark: #006cd2; --vp-c-brand-darker: #004baa; --vp-c-brand-next: #e95ca2; } 25 | 28.75% { --vp-c-brand: #4d8dfa; --vp-c-brand-light: #7eb3ff; --vp-c-brand-lighter: #abdbff; --vp-c-brand-dark: #0069d1; --vp-c-brand-darker: #0048a9; --vp-c-brand-next: #ed5a9a; } 26 | 30% { --vp-c-brand: #638af8; --vp-c-brand-light: #8fb0ff; --vp-c-brand-lighter: #bbd7ff; --vp-c-brand-dark: #3066cf; --vp-c-brand-darker: #0045a7; --vp-c-brand-next: #ef5992; } 27 | 31.25% { --vp-c-brand: #7587f5; --vp-c-brand-light: #9fadff; --vp-c-brand-lighter: #cad4ff; --vp-c-brand-dark: #4963cc; --vp-c-brand-darker: #0941a4; --vp-c-brand-next: #f15989; } 28 | 32.5% { --vp-c-brand: #8583f1; --vp-c-brand-light: #aea9ff; --vp-c-brand-lighter: #d8d1ff; --vp-c-brand-dark: #5b5fc8; --vp-c-brand-darker: #2e3ea1; --vp-c-brand-next: #f25981; } 29 | 33.75% { --vp-c-brand: #9280ed; --vp-c-brand-light: #bca6ff; --vp-c-brand-lighter: #e6cdff; --vp-c-brand-dark: #6a5cc4; --vp-c-brand-darker: #413a9d; --vp-c-brand-next: #f25a79; } 30 | 35% { --vp-c-brand: #9f7ce9; --vp-c-brand-light: #c8a2ff; --vp-c-brand-lighter: #f2c9ff; --vp-c-brand-dark: #7758c0; --vp-c-brand-darker: #503598; --vp-c-brand-next: #f25c71; } 31 | 36.25% { --vp-c-brand: #aa78e3; --vp-c-brand-light: #d39eff; --vp-c-brand-lighter: #fec6ff; --vp-c-brand-dark: #8354bb; --vp-c-brand-darker: #5c3193; --vp-c-brand-next: #f15e69; } 32 | 37.5% { --vp-c-brand: #b574dd; --vp-c-brand-light: #de9bff; --vp-c-brand-lighter: #ffc2ff; --vp-c-brand-dark: #8d50b5; --vp-c-brand-darker: #662c8e; --vp-c-brand-next: #ef6061; } 33 | 38.75% { --vp-c-brand: #be71d7; --vp-c-brand-light: #e897ff; --vp-c-brand-lighter: #ffbfff; --vp-c-brand-dark: #964baf; --vp-c-brand-darker: #6f2688; --vp-c-brand-next: #ed635a; } 34 | 40% { --vp-c-brand: #c76dd1; --vp-c-brand-light: #f194fa; --vp-c-brand-lighter: #ffbcff; --vp-c-brand-dark: #9e47a9; --vp-c-brand-darker: #772082; --vp-c-brand-next: #eb6552; } 35 | 41.25% { --vp-c-brand: #cf69c9; --vp-c-brand-light: #f991f2; --vp-c-brand-lighter: #ffb9ff; --vp-c-brand-dark: #a643a2; --vp-c-brand-darker: #7e197c; --vp-c-brand-next: #e8694b; } 36 | 42.5% { --vp-c-brand: #d566c2; --vp-c-brand-light: #ff8deb; --vp-c-brand-lighter: #ffb6ff; --vp-c-brand-dark: #ac3f9b; --vp-c-brand-darker: #841075; --vp-c-brand-next: #e46c44; } 37 | 43.75% { --vp-c-brand: #dc63ba; --vp-c-brand-light: #ff8be3; --vp-c-brand-lighter: #ffb3ff; --vp-c-brand-dark: #b23b94; --vp-c-brand-darker: #89046f; --vp-c-brand-next: #e06f3d; } 38 | 45% { --vp-c-brand: #e160b3; --vp-c-brand-light: #ff88db; --vp-c-brand-lighter: #ffb1ff; --vp-c-brand-dark: #b7378c; --vp-c-brand-darker: #8d0068; --vp-c-brand-next: #db7336; } 39 | 46.25% { --vp-c-brand: #e65eab; --vp-c-brand-light: #ff86d2; --vp-c-brand-lighter: #ffaffb; --vp-c-brand-dark: #bb3485; --vp-c-brand-darker: #910060; --vp-c-brand-next: #d77630; } 40 | 47.5% { --vp-c-brand: #e95ca2; --vp-c-brand-light: #ff84ca; --vp-c-brand-lighter: #ffadf2; --vp-c-brand-dark: #be317d; --vp-c-brand-darker: #940059; --vp-c-brand-next: #d17a2a; } 41 | 48.75% { --vp-c-brand: #ed5a9a; --vp-c-brand-light: #ff83c1; --vp-c-brand-lighter: #fface9; --vp-c-brand-dark: #c12f75; --vp-c-brand-darker: #970052; --vp-c-brand-next: #cc7d24; } 42 | 50% { --vp-c-brand: #ef5992; --vp-c-brand-light: #ff82b8; --vp-c-brand-lighter: #ffabe0; --vp-c-brand-dark: #c32d6d; --vp-c-brand-darker: #98004b; --vp-c-brand-next: #c6811e; } 43 | 51.25% { --vp-c-brand: #f15989; --vp-c-brand-light: #ff82af; --vp-c-brand-lighter: #ffabd7; --vp-c-brand-dark: #c52d65; --vp-c-brand-darker: #9a0043; --vp-c-brand-next: #bf8418; } 44 | 52.5% { --vp-c-brand: #f25981; --vp-c-brand-light: #ff82a7; --vp-c-brand-lighter: #ffabce; --vp-c-brand-dark: #c52e5e; --vp-c-brand-darker: #9a003c; --vp-c-brand-next: #b98713; } 45 | 53.75% { --vp-c-brand: #f25a79; --vp-c-brand-light: #ff839e; --vp-c-brand-lighter: #ffacc5; --vp-c-brand-dark: #c62f56; --vp-c-brand-darker: #9a0035; --vp-c-brand-next: #b28a0f; } 46 | 55% { --vp-c-brand: #f25c71; --vp-c-brand-light: #ff8496; --vp-c-brand-lighter: #ffadbc; --vp-c-brand-dark: #c5314e; --vp-c-brand-darker: #99002e; --vp-c-brand-next: #ab8d0c; } 47 | 56.25% { --vp-c-brand: #f15e69; --vp-c-brand-light: #ff868d; --vp-c-brand-lighter: #ffaeb4; --vp-c-brand-dark: #c43447; --vp-c-brand-darker: #980027; --vp-c-brand-next: #a3900b; } 48 | 57.5% { --vp-c-brand: #ef6061; --vp-c-brand-light: #ff8885; --vp-c-brand-lighter: #ffb0ab; --vp-c-brand-dark: #c3373f; --vp-c-brand-darker: #970020; --vp-c-brand-next: #9c920d; } 49 | 58.75% { --vp-c-brand: #ed635a; --vp-c-brand-light: #ff8a7d; --vp-c-brand-lighter: #ffb2a3; --vp-c-brand-dark: #c13b38; --vp-c-brand-darker: #940619; --vp-c-brand-next: #949510; } 50 | 60% { --vp-c-brand: #eb6552; --vp-c-brand-light: #ff8d76; --vp-c-brand-lighter: #ffb59b; --vp-c-brand-dark: #be3e31; --vp-c-brand-darker: #921111; --vp-c-brand-next: #8b9715; } 51 | 61.25% { --vp-c-brand: #e8694b; --vp-c-brand-light: #ff8f6e; --vp-c-brand-lighter: #ffb794; --vp-c-brand-dark: #bb4229; --vp-c-brand-darker: #8f1908; --vp-c-brand-next: #83991b; } 52 | 62.5% { --vp-c-brand: #e46c44; --vp-c-brand-light: #ff9367; --vp-c-brand-lighter: #ffba8c; --vp-c-brand-dark: #b74622; --vp-c-brand-darker: #8c1f00; --vp-c-brand-next: #7a9b21; } 53 | 63.75% { --vp-c-brand: #e06f3d; --vp-c-brand-light: #ff9661; --vp-c-brand-lighter: #ffbd86; --vp-c-brand-dark: #b44a1a; --vp-c-brand-darker: #882500; --vp-c-brand-next: #719d27; } 54 | 65% { --vp-c-brand: #db7336; --vp-c-brand-light: #ff995a; --vp-c-brand-lighter: #ffc17f; --vp-c-brand-dark: #af4e11; --vp-c-brand-darker: #842a00; --vp-c-brand-next: #679e2e; } 55 | 66.25% { --vp-c-brand: #d77630; --vp-c-brand-light: #ff9c54; --vp-c-brand-lighter: #ffc47a; --vp-c-brand-dark: #ab5206; --vp-c-brand-darker: #802f00; --vp-c-brand-next: #5da035; } 56 | 67.5% { --vp-c-brand: #d17a2a; --vp-c-brand-light: #fea04f; --vp-c-brand-lighter: #ffc774; --vp-c-brand-dark: #a55600; --vp-c-brand-darker: #7b3300; --vp-c-brand-next: #51a13c; } 57 | 68.75% { --vp-c-brand: #cc7d24; --vp-c-brand-light: #f8a34a; --vp-c-brand-lighter: #ffca70; --vp-c-brand-dark: #a05900; --vp-c-brand-darker: #773700; --vp-c-brand-next: #44a244; } 58 | 70% { --vp-c-brand: #c6811e; --vp-c-brand-light: #f2a646; --vp-c-brand-lighter: #ffce6c; --vp-c-brand-dark: #9b5d00; --vp-c-brand-darker: #713b00; --vp-c-brand-next: #34a44b; } 59 | 71.25% { --vp-c-brand: #bf8418; --vp-c-brand-light: #ebaa42; --vp-c-brand-lighter: #ffd168; --vp-c-brand-dark: #956000; --vp-c-brand-darker: #6c3e00; --vp-c-brand-next: #1ba553; } 60 | 72.5% { --vp-c-brand: #b98713; --vp-c-brand-light: #e4ad3f; --vp-c-brand-lighter: #ffd466; --vp-c-brand-dark: #8e6300; --vp-c-brand-darker: #674100; --vp-c-brand-next: #00a65b; } 61 | 73.75% { --vp-c-brand: #b28a0f; --vp-c-brand-light: #ddb03d; --vp-c-brand-lighter: #ffd764; --vp-c-brand-dark: #886600; --vp-c-brand-darker: #614400; --vp-c-brand-next: #00a663; } 62 | 75% { --vp-c-brand: #ab8d0c; --vp-c-brand-light: #d5b33c; --vp-c-brand-lighter: #ffda63; --vp-c-brand-dark: #816900; --vp-c-brand-darker: #5b4700; --vp-c-brand-next: #00a76c; } 63 | 76.25% { --vp-c-brand: #a3900b; --vp-c-brand-light: #cdb63c; --vp-c-brand-lighter: #f8dd63; --vp-c-brand-dark: #7a6b00; --vp-c-brand-darker: #554900; --vp-c-brand-next: #00a874; } 64 | 77.5% { --vp-c-brand: #9c920d; --vp-c-brand-light: #c5b83d; --vp-c-brand-lighter: #f0e064; --vp-c-brand-dark: #736e00; --vp-c-brand-darker: #4e4b00; --vp-c-brand-next: #00a87d; } 65 | 78.75% { --vp-c-brand: #949510; --vp-c-brand-light: #bdbb3e; --vp-c-brand-lighter: #e7e366; --vp-c-brand-dark: #6c7000; --vp-c-brand-darker: #474d00; --vp-c-brand-next: #00a985; } 66 | 80% { --vp-c-brand: #8b9715; --vp-c-brand-light: #b4bd41; --vp-c-brand-lighter: #dee668; --vp-c-brand-dark: #647200; --vp-c-brand-darker: #404f00; --vp-c-brand-next: #00a98e; } 67 | 81.25% { --vp-c-brand: #83991b; --vp-c-brand-light: #abc045; --vp-c-brand-lighter: #d4e86c; --vp-c-brand-dark: #5c7400; --vp-c-brand-darker: #385100; --vp-c-brand-next: #00a996; } 68 | 82.5% { --vp-c-brand: #7a9b21; --vp-c-brand-light: #a2c249; --vp-c-brand-lighter: #cbea70; --vp-c-brand-dark: #537600; --vp-c-brand-darker: #2f5200; --vp-c-brand-next: #00a99f; } 69 | 83.75% { --vp-c-brand: #719d27; --vp-c-brand-light: #98c44e; --vp-c-brand-lighter: #c1ec75; --vp-c-brand-dark: #4a7700; --vp-c-brand-darker: #255300; --vp-c-brand-next: #00a9a7; } 70 | 85% { --vp-c-brand: #679e2e; --vp-c-brand-light: #8ec654; --vp-c-brand-lighter: #b7ee7a; --vp-c-brand-dark: #407900; --vp-c-brand-darker: #185500; --vp-c-brand-next: #00a9b0; } 71 | 86.25% { --vp-c-brand: #5da035; --vp-c-brand-light: #84c75a; --vp-c-brand-lighter: #acf080; --vp-c-brand-dark: #357a0a; --vp-c-brand-darker: #015600; --vp-c-brand-next: #00a9b8; } 72 | 87.5% { --vp-c-brand: #51a13c; --vp-c-brand-light: #79c961; --vp-c-brand-lighter: #a1f287; --vp-c-brand-dark: #277b16; --vp-c-brand-darker: #005700; --vp-c-brand-next: #00a9c0; } 73 | 88.75% { --vp-c-brand: #44a244; --vp-c-brand-light: #6dca68; --vp-c-brand-lighter: #96f48e; --vp-c-brand-dark: #117c1f; --vp-c-brand-darker: #005700; --vp-c-brand-next: #00a8c7; } 74 | 90% { --vp-c-brand: #34a44b; --vp-c-brand-light: #60cc70; --vp-c-brand-lighter: #89f595; --vp-c-brand-dark: #007d28; --vp-c-brand-darker: #005801; --vp-c-brand-next: #00a8cf; } 75 | 91.25% { --vp-c-brand: #1ba553; --vp-c-brand-light: #51cd77; --vp-c-brand-lighter: #7cf69d; --vp-c-brand-dark: #007e30; --vp-c-brand-darker: #00590d; --vp-c-brand-next: #00a7d5; } 76 | 92.5% { --vp-c-brand: #00a65b; --vp-c-brand-light: #48ce80; --vp-c-brand-lighter: #75f7a6; --vp-c-brand-dark: #007f38; --vp-c-brand-darker: #005917; --vp-c-brand-next: #00a6dc; } 77 | 93.75% { --vp-c-brand: #00a663; --vp-c-brand-light: #48cf88; --vp-c-brand-lighter: #75f8ae; --vp-c-brand-dark: #008040; --vp-c-brand-darker: #005a20; --vp-c-brand-next: #00a6e2; } 78 | 95% { --vp-c-brand: #00a76c; --vp-c-brand-light: #49cf91; --vp-c-brand-lighter: #76f9b7; --vp-c-brand-dark: #008049; --vp-c-brand-darker: #005b28; --vp-c-brand-next: #00a4e7; } 79 | 96.25% { --vp-c-brand: #00a874; --vp-c-brand-light: #49d099; --vp-c-brand-lighter: #76f9c0; --vp-c-brand-dark: #008151; --vp-c-brand-darker: #005c30; --vp-c-brand-next: #00a3ec; } 80 | 97.5% { --vp-c-brand: #00a87d; --vp-c-brand-light: #49d0a2; --vp-c-brand-lighter: #77fac9; --vp-c-brand-dark: #008159; --vp-c-brand-darker: #005c37; --vp-c-brand-next: #00a2f1; } 81 | 98.75% { --vp-c-brand: #00a985; --vp-c-brand-light: #4ad1ab; --vp-c-brand-lighter: #77fad3; --vp-c-brand-dark: #008261; --vp-c-brand-darker: #005d3f; --vp-c-brand-next: #00a0f4; } 82 | 100% { --vp-c-brand: #00a98e; --vp-c-brand-light: #4ad1b4; --vp-c-brand-lighter: #78fadc; --vp-c-brand-dark: #008269; --vp-c-brand-darker: #005d47; --vp-c-brand-next: #009ff7; } 83 | } 84 | 85 | :root { 86 | --vp-c-brand: #00a98e; --vp-c-brand-light: #4ad1b4; --vp-c-brand-lighter: #78fadc; --vp-c-brand-dark: #008269; --vp-c-brand-darker: #005d47; --vp-c-brand-next: #009ff7; 87 | animation: rainbow 40s linear infinite; 88 | } 89 | 90 | @media (prefers-reduced-motion: reduce) { 91 | :root { 92 | animation: none !important; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /.vitepress/theme/useComponents.ts: -------------------------------------------------------------------------------- 1 | export function useComponents(app) { 2 | const comp = import.meta.glob('./components/**/*.vue', { eager: true }) 3 | Object.entries(comp).forEach(([path, component]) => { 4 | const name = path.split('/').pop().replace('.vue', '') 5 | app.component(name, component.default) 6 | }) 7 | } 8 | -------------------------------------------------------------------------------- /.vitepress/theme/vars.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Customize default theme styling by overriding CSS variables: 3 | * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css 4 | */ 5 | 6 | /** 7 | * Colors 8 | * -------------------------------------------------------------------------- */ 9 | 10 | :root { 11 | --vp-c-gutter: var(--vp-c-divider); 12 | --vp-code-block-bg: rgba(125,125,125,0.04); 13 | --vp-code-tab-divider: var(--vp-c-divider); 14 | --vp-code-copy-code-bg: rgba(125,125,125,0.1); 15 | --vp-code-copy-code-hover-bg: rgba(125,125,125,0.2); 16 | --vp-c-disabled-bg: rgba(125,125,125,0.2); 17 | --vp-code-tab-text-color: var(--vp-c-text-2); 18 | --vp-code-tab-active-text-color: var(--vp-c-text-1); 19 | --vp-code-tab-hover-text-color: var(--vp-c-text-1); 20 | --vp-code-copy-code-active-text: var(--vp-c-text-2); 21 | --vp-c-text-dark-3: rgba(56, 56, 56, 0.8); 22 | --vp-c-brand-lightest: var(--vp-c-brand); 23 | 24 | --vp-c-highlight-bg: var(--vp-c-brand-light); 25 | --vp-c-highlight-text: var(--vp-c-bg); 26 | } 27 | 28 | .dark { 29 | --vp-code-block-bg: rgba(0,0,0,0.2); 30 | --vp-c-text-code: #c0cec0; 31 | --vp-code-tab-text-color: var(--vp-c-text-dark-2); 32 | --vp-code-tab-active-text-color: var(--vp-c-text-dark-1); 33 | --vp-code-tab-hover-text-color: var(--vp-c-text-dark-1); 34 | --vp-code-copy-code-active-text: var(--vp-c-text-dark-2); 35 | --vp-c-text-dark-3: var(--vp-c-text-dark-2); 36 | } 37 | 38 | 39 | /** 40 | * Component: Button 41 | * -------------------------------------------------------------------------- */ 42 | 43 | :root { 44 | --vp-button-brand-border: var(--vp-c-brand-light); 45 | --vp-button-brand-text: var(--vp-c-white); 46 | --vp-button-brand-bg: var(--vp-c-brand); 47 | --vp-button-brand-hover-border: var(--vp-c-brand-light); 48 | --vp-button-brand-hover-text: var(--vp-c-white); 49 | --vp-button-brand-hover-bg: var(--vp-c-brand-light); 50 | --vp-button-brand-active-border: var(--vp-c-brand-light); 51 | --vp-button-brand-active-text: var(--vp-c-white); 52 | --vp-button-brand-active-bg: var(--vp-button-brand-bg); 53 | } 54 | 55 | /** 56 | * Component: Home 57 | * -------------------------------------------------------------------------- */ 58 | 59 | :root { 60 | --vp-home-hero-name-color: transparent; 61 | --vp-home-hero-name-background: -webkit-linear-gradient( 62 | 120deg, 63 | var(--vp-c-brand) 30%, 64 | var(--vp-c-brand-next) 65 | ); 66 | --vp-home-hero-image-background-image: linear-gradient( 67 | -45deg, 68 | var(--vp-c-brand) 30%, 69 | var(--vp-c-brand-next) 70 | ); 71 | --vp-home-hero-image-filter: blur(80px); 72 | } 73 | 74 | @media (min-width: 640px) { 75 | :root { 76 | --vp-home-hero-image-filter: blur(120px); 77 | } 78 | } 79 | 80 | @media (min-width: 960px) { 81 | :root { 82 | --vp-home-hero-image-filter: blur(120px); 83 | } 84 | } 85 | 86 | /* Safari has a very bad performance on gradient and filter */ 87 | .browser-safari, .browser-firefox { 88 | --vp-home-hero-image-background-image: transparent; 89 | --vp-home-hero-image-filter: ''; 90 | } 91 | 92 | /** 93 | * Component: Custom Block 94 | * -------------------------------------------------------------------------- */ 95 | 96 | :root { 97 | --vp-custom-block-tip-border: var(--vp-c-brand); 98 | --vp-custom-block-tip-text: var(--vp-c-brand-darker); 99 | --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); 100 | } 101 | 102 | .dark { 103 | --vp-custom-block-tip-border: var(--vp-c-brand); 104 | --vp-custom-block-tip-text: var(--vp-c-brand-lightest); 105 | --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); 106 | } 107 | 108 | /** 109 | * Component: Algolia 110 | * -------------------------------------------------------------------------- */ 111 | 112 | .DocSearch { 113 | --docsearch-primary-color: var(--vp-c-brand) !important; 114 | } 115 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-PRESENT Anthony Fu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 文档转移到cn-docs/unocss 3 |

4 | 5 | 6 |

7 | 8 |

9 | 10 |

11 | UnoCSS 12 |

13 |

14 | 即时按需的原子级 CSS 引擎 15 |

16 | 17 |

18 | 中文文档英文文档 19 |

20 | 21 | 22 | -------------------------------------------------------------------------------- /about/index.md: -------------------------------------------------------------------------------- 1 | # 关于本站 2 | 3 | 本站是社区翻译的 UnoCSS 中文文档,文档中所有内容均由[UnoCSS 官网](https://unocss.org/)翻译而来,感谢 UnoCSS 团队的无私奉献。 4 | 5 | 本站由社区维护,由[Alfred-Skyblue](https://github.com/Alfred-Skyblue)发起,若有用词不当或者翻译错误的地方,欢迎提出 PR 或者 Issue,我们会及时修改,感谢您的参与。 6 | 7 | ## 联系我 8 | 9 | - [GitHub](https://github.com/Alfred-Skyblue) 10 | - 微信 11 | 12 | -------------------------------------------------------------------------------- /config/autocomplete.md: -------------------------------------------------------------------------------- 1 | # 自动完成 2 | 3 | UnoCSS 的智能建议在演示平台和[VS Code 扩展](/integrations/vscode)中可以进行定制。 4 | 5 | ```ts 6 | autocomplete: { 7 | templates: [ 8 | // 主题推断 9 | 'bg-$color/', 10 | // 简写 11 | 'text-', 12 | // 逻辑或组合 13 | '(b|border)-(solid|dashed|dotted|double|hidden|none)', 14 | // 常量 15 | 'w-half', 16 | ], 17 | shorthands: { 18 | // 等同于 `opacity: "(0|10|20|30|40|50|60|70|90|100)"` 19 | 'opacity': Array.from({ length: 11 }, (_, i) => i * 10), 20 | 'font-size': '(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl)', 21 | // 覆盖内置的简写 22 | 'num': '(0|1|2|3|4|5|6|7|8|9)' 23 | }, 24 | extractors: [ 25 | // ...extractors 26 | ] 27 | } 28 | ``` 29 | 30 | - `templates` 使用简单的 DSL 来指定自动完成建议。 31 | 32 | - `shorthands` 是一个简写名称与其模板的映射。如果是 `Array`,则它将是一个逻辑或组合。 33 | 34 | - `extractors` 用于挑选可能的类并将类名样式建议转换为正确的格式。例如,您可以查看我们如何实现[属性化自动完成提取器](https://github.com/unocss/unocss/blob/main/packages/preset-attributify/src/autocomplete.ts)。 35 | 36 | - 欲了解更多帮助,请参考[这里](/tools/autocomplete)。 37 | -------------------------------------------------------------------------------- /config/extractors.md: -------------------------------------------------------------------------------- 1 | # 提取器 2 | 3 | 提取器用于从源代码中提取工具的使用情况。 4 | 5 | 默认情况下,会使用 [extractorSplit](https://github.com/unocss/unocss/blob/main/packages/core/src/extractors/split.ts) 进行拆分。该提取器会将源代码拆分为标记,然后直接提供给引擎。 6 | 7 | 您也可以提供自己的提取器来从源代码中提取工具的使用情况。 8 | 9 | 例如,您可以查看我们如何实现 [pug 提取器](https://github.com/unocss/unocss/tree/main/packages/extractor-pug) 或 [attributify 提取器](https://github.com/unocss/unocss/blob/main/packages/preset-attributify/src/extractor.ts)。 10 | -------------------------------------------------------------------------------- /config/index.md: -------------------------------------------------------------------------------- 1 | # 配置 2 | 3 | 配置是 UnoCSS 强大的来源。 4 | 5 | - [Rules](/config/rules) - 定义原子 CSS 工具类。 6 | - [Shortcuts](/config/shortcuts) - 将多个规则组合成一个简写。 7 | - [Theme](/config/theme) - 定义主题变量。 8 | - [Variants](/config/variants) - 对规则应用自定义约定。 9 | - [Transformers](/config/transformers) - 代码转换器,用于支持约定。 10 | - [Extractors](/config/extractors) - 定义提取工具使用情况的位置和方式。 11 | - [Preflights](/config/preflights) - 定义全局 CSS 规则。 12 | - [Layers](/config/layers) -定义每个工具类层的顺序。 13 | - [Autocomplete](/config/autocomplete) - 定义自定义自动完成建议。 14 | - [Presets](/config/presets) - 针对常见用例预定义的配置。 15 | -------------------------------------------------------------------------------- /config/layers.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 图层 3 | icon: ph:stack-bold 4 | description: UnoCSS 允许您根据需要定义图层。 5 | --- 6 | 7 | # 图层 8 | 9 | CSS 的顺序将影响它们的优先级。虽然我们将[保留规则的顺序](/config/rules#排序),但有时您可能希望将一些工具类分组,以更明确地控制它们的顺序。 10 | 11 | ## 用法 12 | 13 | 与 Tailwind 不同,它提供 3 个固定的图层(`base`,`components`,`utilities`),UnoCSS 允许您根据需要定义图层。要设置图层,您可以将元数据作为您的规则的第三项传递: 14 | 15 | ```ts 16 | rules: [ 17 | [/^m-(\d)$/, ([, d]) => ({ margin: `${d / 4}rem` }), { layer: 'utilities' }], 18 | // 当您省略图层时,它将是 `default` 19 | ['btn', { padding: '4px' }] 20 | ] 21 | ``` 22 | 23 | 这将生成: 24 | 25 | ```css 26 | /* 图层: default */ 27 | .btn { 28 | padding: 4px; 29 | } 30 | /* 图层: utilities */ 31 | .m-2 { 32 | margin: 0.5rem; 33 | } 34 | ``` 35 | 36 | 每个预设样式也可以设置图层: 37 | 38 | ```ts 39 | preflights: [ 40 | { 41 | layer: 'my-layer', 42 | getCSS: async () => (await fetch('my-style.css')).text() 43 | } 44 | ] 45 | ``` 46 | 47 | ## 排序 48 | 49 | 您可以通过以下方式控制图层的顺序: 50 | 51 | 52 | 53 | ```ts 54 | layers: { 55 | components: -1, 56 | default: 1, 57 | utilities: 2, 58 | 'my-layer': 3, 59 | } 60 | ``` 61 | 62 | 未指定顺序的图层将按字母顺序排序。 63 | 64 | 当您希望在图层之间添加自定义 CSS 时,您可以更新入口模块: 65 | 66 | ```ts 67 | // 'uno:[layer-name].css' 68 | import 'uno:components.css' 69 | // 不是 'components' 和 'utilities' 图层的将会退化到这里 70 | import 'uno.css' 71 | // 您自己的 CSS 72 | import './my-custom.css' 73 | // "utilities" 图层将拥有最高的优先级 74 | import 'uno:utilities.css' 75 | ``` 76 | -------------------------------------------------------------------------------- /config/preflights.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 预检 3 | description: 您可以从配置中注入原始 css 作为预处理。 已解决的主题可用于自定义 css。 4 | --- 5 | 6 | # 预检 7 | 8 | 您可以从配置中注入原始 css 作为预处理。解析的 `theme` 可用于自定义 css。 9 | 10 | 11 | 12 | ```ts 13 | preflights: [ 14 | { 15 | getCSS: ({ theme }) => ` 16 | * { 17 | color: ${theme.colors.gray?.[700] ?? '#333'}; 18 | padding: 0; 19 | margin: 0; 20 | } 21 | ` 22 | } 23 | ] 24 | ``` 25 | -------------------------------------------------------------------------------- /config/presets.md: -------------------------------------------------------------------------------- 1 | # 预设 2 | 3 | 预设是将被合并到主配置中的部分配置。 4 | 5 | 在编写预设时,我们通常会导出一个构造函数,您可以在其中请求一些特定于预设的选项。例如: 6 | 7 | ```ts 8 | // my-preset.ts 9 | import { Preset } from 'unocss' 10 | 11 | export default function myPreset(options: MyPresetOptions): Preset { 12 | return { 13 | name: 'my-preset', 14 | rules: [ 15 | // ... 16 | ], 17 | variants: [ 18 | // ... 19 | ] 20 | // 它支持您在根配置中拥有的大多数配置 21 | } 22 | } 23 | ``` 24 | 25 | 然后用户可以像这样使用它: 26 | 27 | ```ts 28 | // unocss.config.ts 29 | import { defineConfig } from 'unocss' 30 | import myPreset from './my-preset' 31 | 32 | export default defineConfig({ 33 | presets: [ 34 | myPreset({ 35 | /* 预设选项 */ 36 | }) 37 | ] 38 | }) 39 | ``` 40 | 41 | 您可以查看[官方预设](/presets/)和[社区预设](/presets/community)以获取更多示例。 42 | -------------------------------------------------------------------------------- /config/rules.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 规则 3 | description: Writing custom rules for UnoCSS is super easy. 4 | --- 5 | 6 | # 规则 7 | 8 | 规则定义了 UnoCSS 在代码库中查找和生成 CSS 的方式。 9 | 10 | ## 静态规则 11 | 12 | 使用以下示例: 13 | 14 | ```ts 15 | rules: [['m-1', { margin: '0.25rem' }]] 16 | ``` 17 | 18 | 无论何时在用户的代码库中检测到 `m-1`,将生成以下 CSS: 19 | 20 | ```css 21 | .m-1 { 22 | margin: 0.25rem; 23 | } 24 | ``` 25 | 26 | ## 动态规则 27 | 28 | 为了使它更智能,将匹配器更改为正则表达式,将正文更改为函数: 29 | 30 | ```ts 31 | rules: [ 32 | [/^m-(\d+)$/, ([, d]) => ({ margin: `${d / 4}rem` })], 33 | [/^p-(\d+)$/, match => ({ padding: `${match[1] / 4}rem` })] 34 | ] 35 | ``` 36 | 37 | 函数体的第一个参数是匹配结果,你可以解构它以获取匹配的组。 38 | 39 | 例如,使用以下用法: 40 | 41 | ```html 42 |
43 | 47 |
48 | ``` 49 | 50 | 将生成相应的 CSS: 51 | 52 | ```css 53 | .m-100 { 54 | margin: 25rem; 55 | } 56 | .m-3 { 57 | margin: 0.75rem; 58 | } 59 | .p-5 { 60 | padding: 1.25rem; 61 | } 62 | ``` 63 | 64 | 恭喜!现在你拥有了自己的强大的原子 CSS 工具,尽情享用吧! 65 | 66 | ## 完全控制的规则 67 | 68 | ::: warning 69 | 这是一个高级功能,在大多数情况下不需要它。 70 | ::: 71 | 72 | 当你确实需要一些无法由[动态规则](#动态规则)和[自定义变体](/config/variants)的组合涵盖的高级规则时,我们也提供了一种方式,为你提供完全控制生成 CSS 的方式。 73 | 74 | 从动态规则的函数体中返回一个字符串,它将直接传递给生成的 CSS。这也意味着你需要注意诸如 CSS 转义、变体应用、CSS 构造等问题。 75 | 76 | ```ts 77 | // uno.config.ts 78 | import { defineConfig, toEscapedSelector as e } from 'unocss' 79 | 80 | export default defineConfig({ 81 | rules: [ 82 | [ 83 | /^custom-(.+)$/, 84 | ([, name], { rawSelector, currentSelector, variantHandlers, theme }) => { 85 | // 丢弃不匹配的规则 86 | if (name.includes('something')) return 87 | 88 | // 如果你想的话,可以禁用这个规则的变体 89 | if (variantHandlers.length) return 90 | const selector = e(rawSelector) 91 | // 返回一个字符串而不是对象 92 | return ` 93 | ${selector} { 94 | font-size: ${theme.fontSize.sm}; 95 | } 96 | /* 你可以有多条规则 */ 97 | ${selector}::after { 98 | content: 'after'; 99 | } 100 | .foo > ${selector} { 101 | color: red; 102 | } 103 | /* 或媒体查询 */ 104 | @media (min-width: ${theme.breakpoints.sm}) { 105 | ${selector} { 106 | font-size: ${theme.fontSize.sm}; 107 | } 108 | } 109 | ` 110 | } 111 | ] 112 | ] 113 | }) 114 | ``` 115 | 116 | 您可能需要阅读一些代码才能充分利用它。 117 | 118 | ## 排序 119 | 120 | UnoCSS 尊重您在生成 CSS 中定义的规则的顺序。后定义的规则具有更高的优先级。 121 | 122 | ## 规则合并 123 | 124 | 默认情况下,UnoCSS 将合并具有相同属性的 CSS 规则,以最小化 CSS 大小。 125 | 126 | 例如,`
` 将生成以下 CSS 规则: 127 | 128 | ```css 129 | .hover\:m2:hover, 130 | .m-2 { 131 | margin: 0.5rem; 132 | } 133 | ``` 134 | 135 | 而不是两个单独的规则: 136 | 137 | ```css 138 | .hover\:m2:hover { 139 | margin: 0.5rem; 140 | } 141 | .m-2 { 142 | margin: 0.5rem; 143 | } 144 | ``` 145 | -------------------------------------------------------------------------------- /config/shortcuts.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 快捷方式 3 | description: UnoCSS 提供的快捷方式功能类似于 Windi CSS 的功能。 4 | --- 5 | 6 | # 快捷方式 7 | 8 | 快捷方式可以让您将多个规则组合成单个简写,受到[Windi CSS](https://windicss.org/features/shortcuts.html)的启发。 9 | 10 | ## 使用 11 | 12 | 13 | 14 | ```ts 15 | shortcuts: { 16 | // shortcuts to multiple utilities 17 | 'btn': 'py-2 px-4 font-semibold rounded-lg shadow-md', 18 | 'btn-green': 'text-white bg-green-500 hover:bg-green-700', 19 | // single utility alias 20 | 'red': 'text-red-100' 21 | } 22 | ``` 23 | 24 | 除了普通的映射之外,UnoCSS 还允许您定义动态快捷方式。 25 | 26 | 类似于[Rules](/config/rules),动态快捷方式是一个匹配器 RegExp 和一个处理函数的组合。 27 | 28 | ```ts 29 | shortcuts: [ 30 | // you could still have object style 31 | { 32 | btn: 'py-2 px-4 font-semibold rounded-lg shadow-md' 33 | }, 34 | // dynamic shortcuts 35 | [/^btn-(.*)$/, ([, c]) => `bg-${c}-400 text-${c}-100 py-2 px-4 rounded-lg`] 36 | ] 37 | ``` 38 | 39 | 有了这个,我们可以使用 `btn-green` 和 `btn-red` 来生成以下 CSS: 40 | 41 | ```css 42 | .btn-green { 43 | padding-top: 0.5rem; 44 | padding-bottom: 0.5rem; 45 | padding-left: 1rem; 46 | padding-right: 1rem; 47 | --un-bg-opacity: 1; 48 | background-color: rgba(74, 222, 128, var(--un-bg-opacity)); 49 | border-radius: 0.5rem; 50 | --un-text-opacity: 1; 51 | color: rgba(220, 252, 231, var(--un-text-opacity)); 52 | } 53 | .btn-red { 54 | padding-top: 0.5rem; 55 | padding-bottom: 0.5rem; 56 | padding-left: 1rem; 57 | padding-right: 1rem; 58 | --un-bg-opacity: 1; 59 | background-color: rgba(248, 113, 113, var(--un-bg-opacity)); 60 | border-radius: 0.5rem; 61 | --un-text-opacity: 1; 62 | color: rgba(254, 226, 226, var(--un-text-opacity)); 63 | } 64 | ``` 65 | -------------------------------------------------------------------------------- /config/theme.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 主题 3 | description: UnoCSS 还支持设置您在 Tailwind Windi 中可能熟悉的主题系统。 4 | --- 5 | 6 | # 主题 7 | 8 | `UnoCSS` 也支持像 Tailwind / Windi 中的主题系统。在用户级别上,您可以在配置中指定 `theme` 属性,它将与默认主题进行深度合并。 9 | 10 | ## 用法 11 | 12 | 13 | 14 | ```ts 15 | theme: { 16 | // ... 17 | colors: { 18 | 'veryCool': '#0000ff', // class="text-very-cool" 19 | 'brand': { 20 | 'primary': 'hsla(var(--hue, 217), 78%, 51%)', //class="bg-brand-primary" 21 | } 22 | }, 23 | } 24 | ``` 25 | 26 | ## 在 `rules` 中使用 27 | 28 | 在规则中使用主题: 29 | 30 | ```ts 31 | rules: [ 32 | [ 33 | /^text-(.*)$/, 34 | ([, c], { theme }) => { 35 | if (theme.colors[c]) return { color: theme.colors[c] } 36 | } 37 | ] 38 | ] 39 | ``` 40 | 41 | 一个例外是,UnoCSS 将 `breakpoints` 控制权完全留给用户。当提供自定义 `breakpoints` 时,默认值将被覆盖而不是合并。例如: 42 | 43 | 44 | 45 | ```ts 46 | theme: { 47 | // ... 48 | breakpoints: { 49 | sm: '320px', 50 | md: '640px', 51 | }, 52 | } 53 | ``` 54 | 55 | 目前,您只能使用 `sm:` 和 `md:` 断点变量。 56 | 57 | `verticalBreakpoints` 与 `breakpoints` 相同,但用于垂直布局。 58 | -------------------------------------------------------------------------------- /config/transformers.md: -------------------------------------------------------------------------------- 1 | # Transformers(转换器) 2 | 3 | Transformers 用于转换源代码以支持约定。 4 | 5 | 它提供了一个统一的接口来转换源代码以支持约定。 6 | 7 | ```ts 8 | // my-transformer.ts 9 | import { createFilter } from '@rollup/pluginutils' 10 | import { SourceCodeTransformer } from 'unocss' 11 | 12 | export default function myTransformers( 13 | options: MyOptions = {} 14 | ): SourceCodeTransformer { 15 | return { 16 | name: 'my-transformer', 17 | enforce: 'pre', // 在其他transformer之前执行 18 | idFilter() { 19 | // 只转换 .tsx 和 .jsx 文件 20 | return id.match(/\.[tj]sx$/) 21 | }, 22 | async transform(code, id, { uno }) { 23 | // code 是一个 MagicString 实例 24 | code.appendRight(0, '/* my transformer */') 25 | } 26 | } 27 | } 28 | ``` 29 | 30 | 您可以查看[官方的 transformers](/presets/#transformers)了解更多示例。 31 | -------------------------------------------------------------------------------- /config/variants.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 变体 3 | description: 变体允许您对现有规则应用一些变体 4 | --- 5 | 6 | # 变体 7 | 8 | [变体](https://windicss.org/utilities/general/variants.html) 允许您对现有的规则应用一些变化,例如 Tailwind 中的 `hover:` 变体。 9 | 10 | ## 示例 11 | 12 | 13 | 14 | ```ts 15 | variants: [ 16 | // hover: 17 | (matcher) => { 18 | if (!matcher.startsWith('hover:')) 19 | return matcher 20 | return { 21 | // 去掉前缀并将其传递给下一个变体和规则 22 | matcher: matcher.slice(6), 23 | selector: s => `${s}:hover`, 24 | } 25 | } 26 | ], 27 | rules: [ 28 | [/^m-(\d)$/, ([, d]) => ({ margin: `${d / 4}rem` })], 29 | ] 30 | ``` 31 | 32 | - `matcher` 控制变体何时启用。如果返回值是字符串,则将其用作匹配规则的选择器。 33 | - `selector` 提供了自定义生成的 CSS 选择器的可用性。 34 | 35 | ## 内部实现 36 | 37 | 让我们看看匹配 `hover:m-2` 时发生了什么: 38 | 39 | - 用户使用中提取了 `hover:m-2` 40 | - `hover:m-2` 发送给所有变体进行匹配 41 | - `hover:m-2` 被我们的变体匹配并返回 `m-2` 42 | - 结果 `m-2` 将用于下一轮变体匹配 43 | - 如果没有其他变体匹配,`m-2` 将继续匹配规则 44 | - 第一条规则匹配并生成 `.m-2 { margin: 0.5rem; }` 45 | - 最后,我们将我们的变体转换应用于生成的 CSS。在这种情况下,我们将 `:hover` 前缀添加到 `selector` 钩子中。 46 | 47 | 因此,将生成以下 CSS: 48 | 49 | ```css 50 | .hover\:m-2:hover { 51 | margin: 0.5rem; 52 | } 53 | ``` 54 | 55 | 这样,只有当用户悬停在元素上时,才会应用 `m-2`。 56 | 57 | ## 进一步了解 58 | 59 | 变体系统非常强大,本指南无法完全涵盖。您可以查看 [默认预设的实现](https://github.com/unocss/unocss/tree/main/packages/preset-mini/src/_variants) 以了解更高级的用法。 60 | -------------------------------------------------------------------------------- /extractors/arbitrary-variants.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Arbitrary Variants Extractor 3 | --- 4 | 5 | # Arbitrary Variants Extractor 6 | 7 | A more complex extractor to support arbitrary variants for utilities. 8 | 9 | ```html 10 |
11 | ``` 12 | 13 | Will be captured with `[&>*]:m-1` and `[&[open]]:p-2` as variants. 14 | 15 | This extractor is included in [`@unocss/preset-mini`](/presets/mini) as the default extractor. Normally you don't need to install this package manually. 16 | 17 | ## Installation 18 | 19 | ::: code-group 20 | 21 | ```bash [pnpm] 22 | pnpm add -D @unocss/extractor-arbitrary-variants 23 | ``` 24 | 25 | ```bash [yarn] 26 | yarn add -D @unocss/extractor-arbitrary-variants 27 | ``` 28 | 29 | ```bash [npm] 30 | npm install -D @unocss/extractor-arbitrary-variants 31 | ``` 32 | 33 | ::: 34 | 35 | ```ts 36 | import { defineConfig } from 'unocss' 37 | import extractorArbitrary from '@unocss/extractor-arbitrary-variants' 38 | 39 | export default defineConfig({ 40 | extractors: [extractorArbitrary()] 41 | }) 42 | ``` 43 | -------------------------------------------------------------------------------- /extractors/pug.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Pug 提取器 3 | description: UnoCSS 的 Pug 提取器 (@unocssextractor-pug) 4 | --- 5 | 6 | # Pug 提取器 7 | 8 | UnoCSS 的 Pug 提取器: `@unocss/extractor-pug`。 9 | 10 | ## Installation 11 | 12 | ::: code-group 13 | 14 | ```bash [pnpm] 15 | pnpm add -D @unocss/extractor-pug 16 | ``` 17 | 18 | ```bash [yarn] 19 | yarn add -D @unocss/extractor-pug 20 | ``` 21 | 22 | ```bash [npm] 23 | npm install -D @unocss/extractor-pug 24 | ``` 25 | 26 | ::: 27 | 28 | ## 使用 29 | 30 | ```ts 31 | import { defineConfig } from 'unocss' 32 | import { extractorSplit } from '@unocss/core' 33 | import extractorPug from '@unocss/extractor-pug' 34 | 35 | export default defineConfig({ 36 | extractors: [extractorPug(), extractorSplit] 37 | }) 38 | ``` 39 | -------------------------------------------------------------------------------- /extractors/svelte.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Svelte 提取器 3 | --- 4 | 5 | # Svelte 提取器 6 | 7 | 支持从 `class:` 指令中提取类。 8 | 9 | ```html 10 |
11 | ``` 12 | 13 | 将被提取为 `text-orange-400` 并生成: 14 | 15 | ```css 16 | .text-orange-400 { 17 | color: #f6993f; 18 | } 19 | ``` 20 | 21 | ## 安装 22 | 23 | ::: code-group 24 | ```bash [pnpm] 25 | pnpm add -D @unocss/extractor-svelte 26 | ``` 27 | ```bash [yarn] 28 | yarn add -D @unocss/extractor-sve 29 | ``` 30 | ```bash [npm] 31 | npm install -D @unocss/extractor-sve 32 | ``` 33 | ::: 34 | ```ts 35 | // uno.config.js 36 | import { defineConfig } from 'unocss' 37 | import extractorSvelte from '@unocss/extractor-svelte' 38 | 39 | export default defineConfig({ 40 | extractors: [extractorSvelte()] 41 | }) 42 | ``` 43 | -------------------------------------------------------------------------------- /guide/config-file.md: -------------------------------------------------------------------------------- 1 | # 配置文件 2 | 3 | 我们**强烈推荐使用一个专用的 `uno.config.ts` 文件**来配置您的 UnoCSS,以便在 IDE 和其他集成中获得最佳体验。 4 | 5 | 一个完整的配置文件如下所示: 6 | 7 | ```ts 8 | // uno.config.ts 9 | import { 10 | defineConfig, 11 | presetAttributify, 12 | presetIcons, 13 | presetTypography, 14 | presetUno, 15 | presetWebFonts, 16 | transformerDirectives, 17 | transformerVariantGroup 18 | } from 'unocss' 19 | 20 | export default defineConfig({ 21 | shortcuts: [ 22 | // ... 23 | ], 24 | theme: { 25 | colors: { 26 | // ... 27 | } 28 | }, 29 | presets: [ 30 | presetUno(), 31 | presetAttributify(), 32 | presetIcons(), 33 | presetTypography(), 34 | presetWebFonts({ 35 | fonts: { 36 | // ... 37 | } 38 | }) 39 | ], 40 | transformers: [transformerDirectives(), transformerVariantGroup()] 41 | }) 42 | ``` 43 | 44 | 与在 vite.config.ts 或其他工具配置中内联配置相比,专用的配置文件将更好地与[IDEs](/integrations/vscode)和其他工具集成,例如[ESLint plugin](/integrations/eslint),并且能够更好地支持 HMR(热更新)。 45 | 46 | 默认情况下,UnoCSS 将自动在您的项目根目录中查找 `uno.config.{js,ts,mjs,mts}` 或 `unocss.config.{js,ts,mjs,mts}` 文件。您还可以手动指定配置文件,例如在 Vite 中: 47 | 48 | ```ts 49 | // vite.config.ts 50 | import { defineConfig } from 'vite' 51 | import UnoCSS from 'unocss/vite' 52 | 53 | export default defineConfig({ 54 | plugins: [ 55 | UnoCSS({ 56 | configFile: '../my-uno.config.ts' 57 | }) 58 | ] 59 | }) 60 | ``` 61 | 62 | 有关支持的配置选项的完整列表,请参阅[配置参考](/config/)。 63 | -------------------------------------------------------------------------------- /guide/extracting.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # 提取内容 6 | 7 | UnoCSS 的工作原理是从代码库中搜索实用程序的用法,并根据需要生成相应的 CSS。我们称这个过程为**提取**。 8 | 9 | ## 内容来源 10 | 11 | UnoCSS 支持从多个来源提取实用程序的用法: 12 | 13 | - [流水线](#从构建工具流水线中提取) - 直接从构建工具流水线中提取 14 | - [文件系统](#从文件系统中提取) - 通过读取和监视文件从文件系统中提取 15 | - [内联](#从内联文本中提取) - 从内联纯文本中提取 16 | 17 | 来自不同来源的实用程序用法将合并在一起,并生成最终的 CSS。 18 | 19 | ### 从构建工具流水线中提取 20 | 21 | 这在[Vite](/integrations/vite)和[Webpack](/integrations/webpack)集成中得到支持。 22 | 23 | UnoCSS 将读取通过构建工具流水线的内容,并从中提取实用程序的用法。这是最高效和准确的提取方式,因为我们只会智能地提取实际在您的应用中使用的用法,提取过程中不会进行额外的文件 IO 操作。 24 | 25 | 默认情况下,UnoCSS 将从构建流水线中的具有扩展名 `.jsx`、`.tsx`、`.vue`、`.md`、`.html`、`.svelte`、`.astro` 的文件中提取实用程序用法,但不会包括 `.js` 和 `.ts` 文件。 26 | 27 | 要配置它们,您可以更新您的 `uno.config.ts` 文件: 28 | 29 | ```ts 30 | // uno.config.ts 31 | export default defineConfig({ 32 | content: { 33 | pipeline: { 34 | include: [ 35 | // 默认配置 36 | /\.(vue|svelte|[jt]sx|mdx?|astro|elm|php|phtml|html)($|\?)/, 37 | // 包括 js/ts 文件 38 | 'src/**/*.{js,ts}' 39 | ] 40 | // 排除文件 41 | // exclude: [] 42 | } 43 | } 44 | }) 45 | ``` 46 | 47 | 您还可以在文件中的任何位置添加 `@unocss-include` 魔术注释,以告诉 UnoCSS 扫描该文件,或者在配置中添加 `*.js` 或 `*.ts`,以将所有 js/ts 文件包含为扫描目标。 48 | 49 | ```ts 50 | // ./some-utils.js 51 | 52 | // 由于默认情况下不包括 `.js` 文件, 53 | // 下面的注释告诉 UnoCSS 强制扫描此文件。 54 | // @unocss-include 55 | export const classes = { 56 | active: 'bg-primary text-white', 57 | inactive: 'bg-gray-200 text-gray-500' 58 | } 59 | ``` 60 | 61 | 类似地,您还可以添加 `@unocss-ignore` 来绕过对文件的扫描和转换。 62 | 63 | 如果您希望 UnoCSS 跳过一段不需要提取的代码块,您可以使用成对的 `@unocss-skip-start` 和 `@unocss-skip-end`: 64 | 65 | ```html 66 |

绿色 大号

67 | 68 | 69 | 70 |

红色

71 | 72 | ``` 73 | 74 | :::tip 75 | 您可以在任何提取文件中使用 `@unocss-skip-start` 和 `@unocss-skip-end` 魔术注释,必须**成对**使用才能生效。 76 | ::: 77 | 78 | ### 从文件系统中提取 79 | 80 | 在一些情况下,您可能使用的集成无法访问构建工具流水线(例如 [PostCSS](/integrations/postcss) 插件),或者您正在与后端框架集成,代码不会通过流水线处理,您可以手动指定要提取的文件。 81 | 82 | ```ts 83 | // uno.config.ts 84 | export default defineConfig({ 85 | content: { 86 | filesystem: ['src/**/*.php', 'public/*.html'] 87 | } 88 | }) 89 | ``` 90 | 91 | 匹配的文件将直接从文件系统中读取,并在开发模式下监视更改。 92 | 93 | ### 从内联文本中提取 94 | 95 | 此外,您还可以从内联文本中提取实用程序的用法,这些文本可能来自其他地方。 96 | 97 | 您还可以传递一个异步函数来返回内容。但请注意,该函数在构建时只会被调用一次。 98 | 99 | ```ts 100 | // uno.config.ts 101 | export default defineConfig({ 102 | content: { 103 | inline: [ 104 | // 纯文本 105 | '
一些文本
', 106 | // 异步获取器 107 | async () => { 108 | const response = await fetch('https://example.com') 109 | return response.text() 110 | } 111 | ] 112 | } 113 | }) 114 | ``` 115 | 116 | ## 限制 117 | 118 | 由于 UnoCSS 是在**构建时**工作,这意味着只会生成和发送静态呈现的实用程序到您的应用程序。动态使用或在运行时从外部资源获取的实用程序可能**不会**被应用。 119 | 120 | ### 白名单 121 | 122 | 有时您可能想要使用动态的拼接,例如: 123 | 124 | ```html 125 |
126 | 127 | ``` 128 | 129 | 由于 UnoCSS 在构建时使用静态提取,编译时我们无法知道所有实用程序的组合情况。为此,您可以配置 `safelist` 选项。 130 | 131 | ```ts 132 | // uno.config.ts 133 | safelist: 'p-1 p-2 p-3 p-4'.split(' ') 134 | ``` 135 | 136 | 将始终生成相应的 CSS: 137 | 138 | ```css 139 | .p-1 { 140 | padding: 0.25rem; 141 | } 142 | .p-2 { 143 | padding: 0.5rem; 144 | } 145 | .p-3 { 146 | padding: 0.75rem; 147 | } 148 | .p-4 { 149 | padding: 1rem; 150 | } 151 | ``` 152 | 153 | 或者更灵活一些: 154 | 155 | ```ts 156 | // uno.config.ts 157 | safelist: [...Array.from({ length: 4 }, (_, i) => `p-${i + 1}`)] 158 | ``` 159 | 160 | 如果您寻求在运行时进行真正的动态生成,请查看 [@unocss 161 | 162 | /runtime](https://github.com/unocss/unocss/tree/main/packages/runtime) 包。 163 | 164 | ### 黑名单 165 | 166 | 与 `safelist` 类似,您还可以配置 `blocklist` 来排除某些实用程序的生成。与 `safelist` 不同,`blocklist` 同时接受字符串进行精确匹配和正则表达式进行模式匹配。 167 | 168 | ```ts 169 | // uno.config.ts 170 | blocklist: ['p-1', /^p-[2-4]$/] 171 | ``` 172 | 173 | 这将排除 `p-1` 和 `p-2`、`p-3`、`p-4` 的生成。有助于排除一些误报信息。 174 | -------------------------------------------------------------------------------- /guide/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 指南 3 | description: UnoCSS 入门 4 | --- 5 | 6 | # 什么是 UnoCSS? 7 | 8 | UnoCSS 是一个即时的原子化 CSS 引擎,旨在灵活和可扩展。核心是不拘一格的,所有的 CSS 工具类都是通过预设提供的。 9 | 10 | 例如,您可以通过在您的本地 [配置文件](/guide/config-file) 中提供规则来定义自定义 CSS 工具类。 11 | 12 | ```ts 13 | // uno.config.ts 14 | import { defineConfig } from 'unocss' 15 | 16 | export default defineConfig({ 17 | rules: [['m-1', { margin: '1px' }]] 18 | }) 19 | ``` 20 | 21 | 这将在您的项目中添加一个新的 CSS 工具类 `m-1`。由于 UnoCSS 是按需加载的,在您的代码库使用它之前不会产生任何作用。因此,假设我们有一个像这样的组件: 22 | 23 | ```html 24 |
Hello
25 | ``` 26 | 27 | `m-1` 将被检测到,并生成以下 CSS: 28 | 29 | ```css 30 | .m-1 { 31 | margin: 1px; 32 | } 33 | ``` 34 | 35 | 为了使其更加灵活,您可以通过将规则的第一个参数(我们称之为匹配器)更改为正则表达式,并将其主体更改为函数,从而使规则变得动态化,例如: 36 | 37 | ```diff 38 | // uno.config.ts 39 | export default defineConfig({ 40 | rules: [ 41 | - ['m-1', { margin: '1px' }] 42 | + [/^m-([\.\d]+)$/, ([_, num]) => ({ margin: `${num}px` })], 43 | ], 44 | }) 45 | ``` 46 | 47 | 通过这样做,现在您可以拥有任意的 margin 工具类,如 `m-1`、`m-100` 或 `m-52.43`。并且,UnoCSS 只在您使用它们时才会生成这些工具。 48 | 49 | ```html 50 |
Hello
51 |
World
52 | ``` 53 | 54 | ```css 55 | .m-1 { 56 | margin: 1px; 57 | } 58 | .m-7.5 { 59 | margin: 7.5px; 60 | } 61 | ``` 62 | 63 | ## 预设 64 | 65 | 一旦您创建了一些规则,您可以将它们提取到一个预设中,并与他人分享。例如,您可以为您公司的设计系统创建一个预设,并与您的团队共享。 66 | 67 | ```ts 68 | // my-preset.ts 69 | import { Preset } from 'unocss' 70 | 71 | export const myPreset: Preset = { 72 | name: 'my-preset', 73 | rules: [ 74 | [/^m-(\d+)$/, ([_, num]) => ({ margin: `${num}px` })], 75 | [/^p-(\d+)$/, ([_, num]) => ({ padding: `${num}px` })] 76 | ], 77 | variants: [ 78 | /* ... */ 79 | ], 80 | shortcuts: [ 81 | /* ... */ 82 | ] 83 | // ... 84 | } 85 | ``` 86 | 87 | ```ts 88 | // uno.config.ts 89 | import { defineConfig } from 'unocss' 90 | import { myPreset } from './my-preset' 91 | 92 | export default defineConfig({ 93 | presets: [ 94 | myPreset // 您自己的预设 95 | ] 96 | }) 97 | ``` 98 | 99 | 同样的,我们提供了一些 [官方预设](/presets/) 可以让您马上开始使用,您也可以找到很多有趣的 [社区预设](/presets/#community). 100 | 101 | ## 交互式文档 102 | 103 | 您可以在 Playground 中尝试 UnoCSS。或者在 交互式文档 中查找默认预设中的工具类。 104 | 105 | ## 集成 106 | 107 | UnoCSS 集成了各种框架工具: 108 | 109 | 110 | 111 | ## 例子 112 | 113 | 所有示例的源代码都可以在 [/examples](https://github.com/unocss/unocss/tree/main/examples) 目录中找到。 114 | 115 | 116 | -------------------------------------------------------------------------------- /guide/packages.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Packages 3 | description: 'UnoCSS 包:可用的包以及 unocss 中包含和启用的内容。' 4 | outline: deep 5 | --- 6 | 7 | # Packages 8 | 9 | UnoCSS 是一个包含多个包的 monorepo。以下是列出了所有的包以及 unocss 包中包含的内容: 10 | 11 | | Package | Description | Included in `unocss` | Enabled | 12 | | -------------------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | 13 | | [@unocss/core](/tools/core) | 没有预置的核心库 | | - | 14 | | [@unocss/cli](/integrations/cli) | UnoCSS 的命令行工具界面 | | - | 15 | | [@unocss/preset-uno](/presets/uno) | 默认预设 | | | 16 | | [@unocss/preset-mini](/presets/mini) | 最少但必不可少的规则和变体 | | | 17 | | [@unocss/preset-wind](/presets/wind) | Tailwind / Windi CSS 预设 | | | 18 | | [@unocss/preset-attributify](/presets/attributify) | 为其他规则启用属性化模式 | | No | 19 | | [@unocss/preset-tagify](/presets/tagify) | 为其他规则启用标签化模式 | | No | 20 | | [@unocss/preset-icons](/presets/icons) | 由 Iconify 提供支持的纯 CSS 图标解决方案 | | No | 21 | | [@unocss/preset-web-fonts](/presets/web-fonts) | 支持 Web 字体(如 Google Fonts 等) | | No | 22 | | [@unocss/preset-typography](/presets/typography) | 排版预设 | | No | 23 | | [@unocss/preset-rem-to-px](/presets/rem-to-px) | 将 rem 单位转换为 px 单位,用于工具类 | No | No | 24 | | [@unocss/transformer-variant-group](/transformers/variant-group) | Windi CSS 的变体组特性的转换器 | | No | 25 | | [@unocss/transformer-directives](/transformers/directives) | 用于处理 CSS 指令 `@apply` 的转换器 | | No | 26 | | [@unocss/transformer-compile-class](/transformers/compile-class) | 将一组类编译为一个类 | | No | 27 | | [@unocss/transformer-attributify-jsx](/transformers/attributify-jsx) | 在 JSX/TSX 中支持无值的属性化语法 | | No | 28 | | [@unocss/extractor-pug](/extractors/pug) | 用于提取 Pug 中内容的提取器 | No | - | 29 | | [@unocss/extractor-svelte](/extractors/svelte) | 用于提取 Svelte 中内容的提取器 | No | - | 30 | | [@unocss/autocomplete](/tools/autocomplete) | 自动完成 | No | - | 31 | | [@unocss/config](/guide/config-file) | 配置文件加载器 | | - | 32 | | [@unocss/reset](/guide/style-reset) | 常用 CSS 重置集合 | | No | 33 | | [@unocss/vite](/integrations/vite) | Vite 插件 | | - | 34 | | [@unocss/inspector](/tools/inspector) | UnoCSS 的检查器 UI | | - | 35 | | [@unocss/astro](/integrations/astro) | Astro 整合 | | - | 36 | | [@unocss/webpack](/integrations/webpack) | Webpack 插件 | No | - | 37 | | [@unocss/nuxt](/integrations/nuxt) | Nuxt 模块 | No | - | 38 | | [@unocss/svelte-scoped](/integrations/svelte-scoped) | Svelte Scoped Vite plugin + Preprocessor | No | - | 39 | | [@unocss/next](/integrations/next) | Next.js 插件 | No | - | 40 | | [@unocss/runtime](/integrations/runtime) | UnoCSS 的 CSS-in-JS 运行时 | No | - | 41 | | [@unocss/eslint-plugin](/integrations/eslint) | ESLint 插件 | No | - | 42 | | [@unocss/eslint-config](/integrations/eslint) | ESLint 配置 | No | - | 43 | | [@unocss/postcss](/integrations/postcss) | PostCSS 插件 | No | - | 44 | | [VS Code Extension](/integrations/vscode) | vscode 扩展 | - | - | 45 | -------------------------------------------------------------------------------- /guide/presets.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 预设 3 | description: 预设是 UnoCSS 的核心。他们让您在几分钟内制作自己的自定义框架。 4 | outline: deep 5 | --- 6 | 7 | # 预设 8 | 9 | 预设是 UnoCSS 的核心。他们让您在几分钟内制作自己的自定义框架。 10 | 11 | ### 使用预设 12 | 13 | 为您的项目添加预设: 14 | 15 | ```ts 16 | // uno.config.ts 17 | import { defineConfig, presetAttributify, presetUno } from 'unocss' 18 | 19 | export default defineConfig({ 20 | presets: [ 21 | presetAttributify({ 22 | /* 预设选项 */ 23 | }), 24 | presetUno() 25 | // ...自定义预设 26 | ] 27 | }) 28 | ``` 29 | 30 | 当指定了 `presets` 选项时,将会忽略默认预设。 31 | 32 | 要禁用默认预设,您可以将 `presets` 设置为空数组: 33 | 34 | ```ts 35 | // uno.config.ts 36 | import { defineConfig } from 'unocss' 37 | 38 | export default defineConfig({ 39 | presets: [], // 禁用默认预设 40 | rules: [ 41 | // 您的自定义规则 42 | ] 43 | }) 44 | ``` 45 | 46 | 您可以在[官方预设](/presets/)和[社区预设](/presets/community)中查看更多预设选项。 47 | -------------------------------------------------------------------------------- /guide/style-reset.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 样式重置 3 | description: UnoCSS 在默认情况下不提供样式重置或预检以获得最大的灵活性,并且不会填充您的全局 CSS。 4 | outline: deep 5 | --- 6 | 7 | # 浏览器样式重置 8 | 9 | UnoCSS 默认情况下不提供样式重置或预检以实现最大灵活性,并且不会填充全局 CSS。如果您将 UnoCSS 与其他 CSS 框架一起使用,它们可能已经为您完成了重置。如果您单独使用 UnoCSS,则可以使用 [Normalize.css](https://github.com/csstools/normalize.css)等重置库。 10 | 11 | 我们还为您提供了一些快速选择的样式重置: 12 | 13 | ## 安装 14 | 15 | ::: code-group 16 | 17 | ```bash [pnpm] 18 | pnpm add @unocss/reset 19 | ``` 20 | 21 | ```bash [yarn] 22 | yarn add @unocss/reset 23 | ``` 24 | 25 | ```bash [npm] 26 | npm install @unocss/reset 27 | ``` 28 | 29 | ::: 30 | 31 | ## Usage 32 | 33 | 您可以在 `main.js` 中添加以下任意一个重置样式表。 34 | 35 | ### normalize.css 36 | 37 | 来源: https://github.com/csstools/normalize.css 38 | 39 | ```ts 40 | import '@unocss/reset/normalize.css' 41 | ``` 42 | 43 | ### sanitize.css 44 | 45 | 来源: https://github.com/csstools/sanitize.css 46 | 47 | ```ts 48 | import '@unocss/reset/sanitize/sanitize.css' 49 | import '@unocss/reset/sanitize/assets.css' 50 | ``` 51 | 52 | ### Eric Meyer 53 | 54 | 来源: https://meyerweb.com/eric/tools/css/reset/index.html 55 | 56 | ```ts 57 | import '@unocss/reset/eric-meyer.css' 58 | ``` 59 | 60 | ### Tailwind 61 | 62 | ```ts 63 | import '@unocss/reset/tailwind.css' 64 | ``` 65 | 66 | ### Tailwind compat 67 | 68 | ```ts 69 | import '@unocss/reset/tailwind-compat.css' 70 | ``` 71 | 72 | 这个样式表基于 [Tailwind reset](#tailwind),只是去除了按钮的背景颜色覆盖,以避免与 UI 框架发生冲突。请[参阅链接的问题 #2127](https://github.com/unocss/unocss/issues/2127).。 73 | 74 | ::: code-group 75 | 76 | ```css [Before] 77 | button, 78 | [type='button'], 79 | [type='reset'], 80 | [type='submit'] { 81 | -webkit-appearance: button; /* 1 */ 82 | background-color: transparent; /* 2 */ 83 | background-image: none; /* 2 */ 84 | } 85 | ``` 86 | 87 | ```css [After] 88 | button, 89 | [type='button'], 90 | [type='reset'], 91 | [type='submit'] { 92 | -webkit-appearance: button; /* 1 */ 93 | /*background-color: transparent; !* 2 *!*/ 94 | background-image: none; /* 2 */ 95 | } 96 | ``` 97 | 98 | ::: 99 | -------------------------------------------------------------------------------- /guide/why.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # 为什么是 UnoCSS? 6 | 7 | ## 动机 8 | 9 | 我们建议您阅读由 UnoCSS 的创建者 [Anthony Fu](https://antfu.me/) 撰写的博客文章 [Reimagine Atomic CSS](https://antfu.me/posts/reimagine-atomic-css-zh),以更好地理解 UnoCSS 背后的动机。 10 | 11 | ## UnoCSS 与其他框架的不同之处 12 | 13 | ### Windi CSS 14 | 15 | UnoCSS 由 [Windi CSS](https://windicss.org/) 团队的成员创建,灵感来源于我们在 Windi CSS 中的工作。虽然 Windi CSS 在 2023 年 3 月停止了维护,但您可以将 UnoCSS 看作是 Windi CSS 的"精神继承者"。 16 | 17 | UnoCSS 继承了 Windi 的按需自然样式、[属性模式](/presets/attributify)、[快捷方式](/config/shortcuts)、[变体组](/transformers/variant-group)、[编译模式](/transformers/compile-class)等特性,并在此基础上构建了极具可扩展性和性能的 UnoCSS,从而引入了新的功能,如[纯 CSS 图标](/presets/icons)、[无值属性模式](/presets/attributify#无值属性)、[标签化](/presets/tagify)、[Web 字体](/presets/web-fonts)等。 18 | 19 | 最重要的是,UnoCSS 作为一种原子级 CSS 引擎,所有的功能都是可选的,并且可以轻松创建自己的约定、设计系统和预设 - 您可以选择需要的功能组合。 20 | 21 | ### Tailwind CSS 22 | 23 | Windi CSS 和 UnoCSS 都从[Tailwind CSS](https://tailwindcss.com/)中汲取了很多灵感。由于 UnoCSS 是从头开始构建的,因此我们可以很好地了解原子 CSS 是如何通过前期的艺术和抽象转化为优雅且强大的 API 的。虽然 Tailwind CSS 和 UnoCSS 有不同的设计目标,因此无法直接进行比较,但我们将列举一些差异: 24 | 25 | Tailwind CSS 是一个 PostCSS 插件,而 UnoCSS 是一个具有多种一流构建工具集成的同构引擎(包括[PostCSS 插件](/integrations/postcss))。这意味着 UnoCSS 可以在不同的地方更加灵活地使用(例如,[CDN 运行时](/integrations/runtime),可以动态生成 CSS),并且可以与构建工具深度集成,提供更好的 HMR、性能和开发者体验(例如,[Inspector](/tools/inspector))。 26 | 27 | 从技术上讲,抛开权衡不谈,UnoCSS 也被设计成完全可扩展和可定制化,而 Tailwind CSS 则更加偏向于一种观点。在 Tailwind CSS 上构建自定义设计系统(或设计令牌)可能会很困难,你无法真正摆脱 Tailwind CSS 的约定。而在 UnoCSS 上,您可以完全控制地构建几乎任何您想要的东西。例如,我们在一个[单一的预设](/presets/wind)中实现了整个与 Tailwind CSS 兼容的工具,而且还有许多其他有趣哲学的[社区预设](/presets/community)。 28 | 29 | 由于 UnoCSS 提供的灵活性,我们能够在其上尝试许多创新功能,例如: 30 | 31 | - [纯 CSS 图标](/presets/icons) 32 | - [属性模式](/presets/attributify) 33 | - [变体组](/transformers/variant-group) 34 | - [快捷方式](/config/shortcuts) 35 | - [标签化](/presets/tagify) 36 | - [Web 字体](/presets/web-fonts) 37 | - [CDN 运行时](/integrations/runtime) 38 | - [检查器](/tools/inspector) 39 | 40 | UnoCSS 相较于 Tailwind CSS 的缺点是不支持 Tailwind 的插件系统或配置,这意味着从一个定制化程度很高的 Tailwind CSS 项目迁移可能会更加困难。这是一个有意的决策,旨在使 UnoCSS 高性能和可扩展,我们相信这种权衡是值得的。 41 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | title: 'UnoCSS 中文文档' 4 | 5 | hero: 6 | image: 7 | src: /logo.svg 8 | alt: UnoCSS 9 | name: 'UnoCSS' 10 | text: 即时按需的原子级CSS引擎 11 | tagline: 可定制的·强大的·快速的·快乐的 12 | actions: 13 | - theme: brand 14 | text: 入门 15 | link: /guide/ 16 | - theme: alt 17 | text: 交互式文档 18 | link: https://unocss.dev/interactive/ 19 | target: _blank 20 | - theme: alt 21 | text: 演练场 22 | link: https://unocss.dev/play/ 23 | target: _blank 24 | 25 | features: 26 | - icon: 27 | title: 完全可定制 28 | details: 无核心工具,所有功能都通过预设提供。 29 | link: /guide/ 30 | linkText: 开始使用 31 | - icon: 32 | title: 即时的 33 | details: 无解析、无抽象语法树、无扫描。它比 Windi CSS 或 Tailwind JIT 快5倍。 34 | - icon: 35 | title: 轻量级的 36 | details: '零依赖且适用于浏览器:~6kb min+brotli' 37 | - icon: 38 | title: 丰富的集成能力 39 | details: '对Vite、Webpack、PostCSS、CLI、VS Code、ESLint等工具的一流支持' 40 | link: /integrations/vite 41 | linkText: '了解更多' 42 | - icon: 43 | title: 快捷方式 44 | details: '通过别名或动态分组实现工具类' 45 | link: /config/shortcuts 46 | linkText: '配置和使用' 47 | - icon: 48 | title: '属性化模式' 49 | details: '在属性中对工具类进行分组' 50 | link: /presets/attributify 51 | linkText: '@unocss/preset-attributify' 52 | - icon: 53 | title: 纯 CSS 图标 54 | details: '将任何图标作为单个类使用' 55 | link: /presets/icons 56 | linkText: '@unocss/preset-icons' 57 | - icon: 58 | title: 变体组 59 | details: '使用常见前缀的组合工具类的速记方式' 60 | link: /transformers/variant-group 61 | linkText: '@unocss/transformer-variant-group' 62 | - icon: 63 | title: CSS 指令 64 | details: '使用 @apply 指令在 CSS 中重用工具类' 65 | link: /transformers/directives 66 | linkText: '@unocss/transformer-directives' 67 | - icon: 68 | title: 编译模式 69 | details: '在构建时将多个类合成为一个类' 70 | link: /transformers/compile-class 71 | linkText: '@unocss/transformer-compile-class' 72 | - icon: 73 | title: 检查器 74 | details: '交互式检查和调试' 75 | link: /tools/inspector 76 | linkText: '@unocss/inspector' 77 | - icon: 78 | title: CDN 运行时构建 79 | details: '只需一行 CDN 引入即可使用 UnoCSS' 80 | link: /integrations/runtime 81 | linkText: '@unocss/runtime' 82 | --- 83 | -------------------------------------------------------------------------------- /integrations/astro.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: UnoCSS Astro 集成 3 | description: The UnoCSS integration for Astro (@unocss/astro). 4 | --- 5 | 6 | # Astro 继承 7 | 8 | UnoCSS 在 [Astro](https://astro.build/) 中的集成:`@unocss/astro`。查看[示例](https://github.com/unocss/unocss/tree/main/examples/astro)。 9 | 10 | ## 安装 11 | 12 | ::: code-group 13 | 14 | ```bash [pnpm] 15 | pnpm add -D unocss 16 | ``` 17 | 18 | ```bash [yarn] 19 | yarn add -D unocss 20 | ``` 21 | 22 | ```bash [npm] 23 | npm install -D unocss 24 | ``` 25 | 26 | ::: 27 | 28 | ```ts 29 | // astro.config.ts 30 | import { defineConfig } from 'astro/config' 31 | import UnoCSS from 'unocss/astro' 32 | 33 | export default defineConfig({ 34 | integrations: [UnoCSS()] 35 | }) 36 | ``` 37 | 38 | 创建一个 `uno.config.ts` 文件: 39 | 40 | ```ts 41 | // uno.config.ts 42 | import { defineConfig } from 'unocss' 43 | 44 | export default defineConfig({ 45 | // ...UnoCSS 选项 46 | }) 47 | ``` 48 | 49 | ### 样式重置 50 | 51 | 默认情况下,[浏览器样式重置](/guide/style-reset) 不会被注入。要启用它,请安装 `@unocss/reset` 包: 52 | 53 | ::: code-group 54 | 55 | ```bash [pnpm] 56 | pnpm add -D @unocss/reset 57 | ``` 58 | 59 | ```bash [yarn] 60 | yarn add -D @unocss/reset 61 | ``` 62 | 63 | ```bash [npm] 64 | npm install -D @unocss/reset 65 | ``` 66 | 67 | ::: 68 | 69 | 并更新您的 `astro.config.ts`: 70 | 71 | ```ts 72 | // astro.config.ts 73 | import { defineConfig } from 'astro/config' 74 | import UnoCSS from 'unocss/astro' 75 | 76 | export default defineConfig({ 77 | integrations: [ 78 | UnoCSS({ 79 | injectReset: true // 或者重置文件的路径 80 | }) 81 | ] 82 | }) 83 | ``` 84 | 85 | ### 不使用预设 86 | 87 | 此插件不带任何默认预设。 88 | 89 | ::: code-group 90 | 91 | ```bash [pnpm] 92 | pnpm add -D @unocss/astro 93 | ``` 94 | 95 | ```bash [yarn] 96 | yarn add -D @unocss/astro 97 | ``` 98 | 99 | ```bash [npm] 100 | npm install -D @unocss/astro 101 | ``` 102 | 103 | ::: 104 | 105 | ```ts 106 | // astro.config.mjs 107 | import UnoCSS from '@unocss/astro' 108 | 109 | export default { 110 | integrations: [UnoCSS()] 111 | } 112 | ``` 113 | 114 | 更多详情,请参考 [Vite 插件](/integrations/vite)。 115 | 116 | ::: info 117 | 如果你正在构建一个基于 UnoCSS 的元框架,请[参考这个文件](https://github.com/unocss/unocss/blob/main/packages/unocss/src/astro.ts)中的示例,了解如何绑定默认预设。 118 | ::: 119 | 120 | ## 注意事项 121 | 122 | [`client:only`](https://docs.astro.build/en/reference/directives-reference/#clientonly) 组件必须放置在 [`components`](https://docs.astro.build/en/core-concepts/project-structure/#srccomponents) 文件夹中,或者添加到 UnoCSS 的 `extraContent` 配置中,以便进行处理。 123 | -------------------------------------------------------------------------------- /integrations/cli.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: UnoCSS CLI 3 | description: The CLI for UnoCSS (@unocss/cli). 4 | --- 5 | 6 | # CLI 7 | 8 | UnoCSS 的命令行界面:`@unocss/cli`。 9 | 10 | - 🍱 适用于传统的后端框架,如 Laravel 或 Kirby 11 | - 👀 包含[监听模式](#开发模式) 12 | - 🔌 支持通过[`uno.config.ts`](#配置)进行自定义配置 13 | 14 | ## 安装 15 | 16 | 这个包已经包含在 `unocss` 包中: 17 | 18 | ::: code-group 19 | 20 | ```bash [pnpm] 21 | pnpm add -D unocss 22 | ``` 23 | 24 | ```bash [yarn] 25 | yarn add -D unocss 26 | ``` 27 | 28 | ```bash [npm] 29 | npm install -D unocss 30 | ``` 31 | 32 | ::: 33 | 34 | 你也可以单独安装 `@unocss/cli` 包: 35 | 36 | ::: code-group 37 | 38 | ```bash [pnpm] 39 | pnpm add -D @unocss/cli 40 | ``` 41 | 42 | ```bash [yarn] 43 | yarn add -D @unocss/cli 44 | ``` 45 | 46 | ```bash [npm] 47 | npm install -D @unocss/cli 48 | ``` 49 | 50 | ::: 51 | 52 | ## 使用 53 | 54 | 你可以将多个 glob 模式传递给 `@unocss/cli`: 55 | 56 | ```bash 57 | unocss "site/snippets/**/*.php" "site/templates/**/*.php" 58 | ``` 59 | 60 | 配置示例: 61 | 62 | ::: info 63 | 确保在 npm 脚本的 glob 模式中添加转义符号。 64 | ::: 65 | 66 | ```json 67 | { 68 | "scripts": { 69 | "dev": "unocss \"site/{snippets,templates}/**/*.php\" --watch", 70 | "build": "unocss \"site/{snippets,templates}/**/*.php\"" 71 | }, 72 | "devDependencies": { 73 | "@unocss/cli": "latest" 74 | } 75 | } 76 | ``` 77 | 78 | ### 开发模式 79 | 80 | 添加 --watch (或 -w) 标志以启用文件变动监听: 81 | 82 | ```bash 83 | unocss "site/{snippets,templates}/**/*.php" --watch 84 | ``` 85 | 86 | ### 生产模式 87 | 88 | ```bash 89 | unocss "site/{snippets,templates}/**/*.php" 90 | ``` 91 | 92 | 默认情况下,生成的 `uno.css` 将会保存在当前目录中。 93 | 94 | ## 内置功能 95 | 96 | ### 配置 97 | 98 | 在项目的根目录下创建一个 `uno.config.js` 或 `uno.config.ts` 配置文件来自定义 UnoCSS。 99 | 100 | ```ts 101 | import { defineConfig } from 'unocss' 102 | 103 | export default defineConfig({ 104 | cli: { 105 | entry: {} // CliEntryItem | CliEntryItem[] 106 | } 107 | // ... 108 | }) 109 | 110 | interface CliEntryItem { 111 | /** 112 | * 匹配文件的glob模式 113 | */ 114 | patterns: string[] 115 | /** 116 | * 生成的UnoCSS文件的输出文件名 117 | */ 118 | outFile: string 119 | } 120 | ``` 121 | 122 | 有关选项的完整列表,请查看[UnoCSS 配置文档](/config/)。 123 | 124 | ## 选项 125 | 126 | | Options | | 127 | | -------------------------- | ------------------------------------------------------------------------ | 128 | | `-v, --version` | 显示当前 UnoCSS 的版本号 | 129 | | `-c, --config-file ` | 配置文件 | 130 | | `-o, --out-file ` | 生成的 UnoCSS 文件的输出文件名。默认为当前工作目录中的 `uno.css` | 131 | | `--stdout` | 将生成的 UnoCSS 文件写入 STDOUT。会导致 `--watch` 和 `--out-file` 被忽略 | 132 | | `-w, --watch` | 指示是否应监视 glob 模式找到的文件 | 133 | | `--preflights` | 启用预检样式 | 134 | | `-m, --minify` | 缩小生成的 CSS | 135 | | `-h, --help` | 显示可用的 CLI 命令 | 136 | -------------------------------------------------------------------------------- /integrations/eslint.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: UnoCSS ESLint 配置 3 | description: UnoCSS 的 ESLint 配置 (@unocsseslint-config)。 4 | --- 5 | 6 | # ESLint 配置 7 | 8 | UnoCSS 的 ESLint 配置: `@unocss/eslint-config`. 9 | 10 | ## 安装 11 | 12 | ::: code-group 13 | 14 | ```bash [pnpm] 15 | pnpm add -D @unocss/eslint-config 16 | ``` 17 | 18 | ```bash [yarn] 19 | yarn add -D @unocss/eslint-config 20 | ``` 21 | 22 | ```bash [npm] 23 | npm install -D @unocss/eslint-config 24 | ``` 25 | 26 | ::: 27 | 28 | In `.eslintrc`: 29 | 30 | ```json 31 | { 32 | "extends": ["@unocss"] 33 | } 34 | ``` 35 | 36 | ## 规则 37 | 38 | - `@unocss/order` - 对类选择器执行特定顺序。 39 | - `@unocss/order-attributify` - 对属性选择器执行特定顺序。 40 | 41 | ## Prior Arts 42 | 43 | 感谢 [@devunt](https://github.com/devunt) 的 [eslint-plugin-unocss](https://github.com/devunt/eslint-plugin-unocss)。 44 | -------------------------------------------------------------------------------- /integrations/index.md: -------------------------------------------------------------------------------- 1 | # 集成 2 | 3 | ### 框架 / 工具 4 | 5 | UnoCSS 针对各种框架和工具提供了集成: 6 | 7 | 8 | 9 | ### 示例 10 | 11 | 所有示例的源代码都可以在 [/examples](https://github.com/unocss/unocss/tree/main/examples) 目录中找到。 12 | 13 | 14 | -------------------------------------------------------------------------------- /integrations/jetbrains.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: JetBrains社区 UnoCSS 插件 3 | --- 4 | 5 | # JetBrains IDEs 插件 6 | 7 | 这是一个由社区开发的[插件](https://github.com/re-ovo/unocss-intellij),为 JetBrains IDEs 提供了对 UnoCSS 的支持。 8 | 9 | :::info 10 | 注意:这是一个**由社区维护的插件,不受 UnoCSS 团队审核或维护**。在使用之前,请自行进行调查研究。如果您在使用此插件时遇到任何问题,请报告给 [re-ovo/unocss-intellij](https://github.com/re-ovo/unocss-intellij)。 11 | ::: 12 | 13 | ## 安装 14 | 15 | [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/22204-unocss) 16 | 17 | ## 功能 18 | 19 | - UnoCSS 类的自动完成 20 | - UnoCSS 类的悬停文档 21 | - 代码折叠 22 | - 颜色/图标预览 23 | 24 | ## 缺陷报告 / 功能请求 25 | 26 | 请在 [问题跟踪器](https://github.com/re-ovo/unocss-intellij/issues) 中报告。 27 | -------------------------------------------------------------------------------- /integrations/next.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Next.js 3 | description: UnoCSS 和 Next.js 入门。 4 | --- 5 | 6 | # Next.js 7 | 8 | // TODO: link to examples 9 | 10 | UnoCSS 和 Next.js 入门。 11 | 12 | ## 设置 13 | 14 | ### 安装 15 | 16 | ::: code-group 17 | 18 | ```bash [pnpm] 19 | pnpm add -D unocss @unocss/webpack 20 | ``` 21 | 22 | ```bash [yarn] 23 | yarn add -D unocss @unocss/webpack 24 | ``` 25 | 26 | ```bash [npm] 27 | npm install -D unocss @unocss/webpack 28 | ``` 29 | 30 | ::: 31 | 32 | ### 配置 33 | 34 | 在项目根目录创建 `uno.config.ts`。 35 | 36 | ```ts 37 | // uno.config.ts 38 | import { 39 | defineConfig, 40 | presetAttributify, 41 | presetIcons, 42 | presetUno, 43 | presetWebFonts 44 | } from 'unocss' 45 | 46 | export default defineConfig({ 47 | presets: [ 48 | presetUno() 49 | // ... 50 | ] 51 | }) 52 | ``` 53 | 54 | ### 添加插件 55 | 56 | 然后将 UnoCSS 添加为 webpack 的插件,通过 `next.config.js`。 57 | 58 | ```js{9} 59 | // next.config.js 60 | const UnoCSS = require('@unocss/webpack').default 61 | 62 | /** @type {import('next').NextConfig} */ 63 | const nextConfig = { 64 | reactStrictMode: true, 65 | webpack: (config) => { 66 | config.plugins.push( 67 | UnoCSS(), 68 | ) 69 | return config 70 | }, 71 | } 72 | 73 | module.exports = nextConfig 74 | ``` 75 | 76 | ### 导入样式 77 | 78 | 然后在 `_app.tsx` 中导入 `uno.css`。 79 | 80 | ```tsx 81 | // _app.tsx 82 | import '@unocss/reset/tailwind.css' 83 | import 'uno.css' 84 | 85 | import type { AppProps } from 'next/app' 86 | 87 | function MyApp({ Component, pageProps }: AppProps) { 88 | return 89 | } 90 | 91 | export default MyApp 92 | ``` 93 | 94 | ## 使用 95 | 96 | 使用 `unocss` 为您的组件添加样式! 97 | 98 | ```tsx 99 | /* index.tsx */ 100 | const Home: NextPage = () => { 101 | return ( 102 | <> 103 |
104 | 105 | Nextjs 106 | 107 |
108 | 109 |
110 | 111 | ) 112 | } 113 | ``` 114 | 115 | ## 热更新 116 | 117 | 为了支持 HMR,您需要禁用 webpack 的缓存。 118 | 119 | ```js{5} 120 | // next.config.js 121 | const nextConfig = { 122 | reactStrictMode: true, 123 | webpack: (config) => { 124 | + config.cache = false 125 | config.plugins.push(UnoCSS()) 126 | return config 127 | } 128 | } 129 | ``` 130 | 131 | ## 故障排除 132 | 133 | ### 关于虚拟模块的错误 134 | 135 | ```bash 136 | Error: ENOENT: no such file or directory, open '.../_virtual_/__uno.css' 137 | ``` 138 | 139 | 尝试删除 `.next` 目录并重新启动开发服务器。 140 | 141 | ### 其他问题 142 | 143 | 您可能需要将目标升级到至少 `es2015` 在您的 `tsconfig.json` 文件中以构建您的项目。 144 | 145 | 默认情况下不支持扩展名为 .js 的文件。将您的文件扩展名更改为 .jsx 或尝试使用 `include: \.js` 在您的配置中包含 js 文件。 [了解更多](https://github.com/unocss/unocss#scanning)。 146 | -------------------------------------------------------------------------------- /integrations/nuxt.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: UnoCSS Nuxt 模块 3 | description: UnoCSS 的 Nuxt 模块。 4 | --- 5 | 6 | # Nuxt Module 7 | 8 | UnoCSS 的 Nuxt 模块。 9 | 10 | ## 安装 11 | 12 | ::: code-group 13 | 14 | ```bash [pnpm] 15 | pnpm add -D @unocss/nuxt 16 | ``` 17 | 18 | ```bash [yarn] 19 | yarn add -D @unocss/nuxt 20 | ``` 21 | 22 | ```bash [npm] 23 | npm install -D @unocss/nuxt 24 | ``` 25 | 26 | ::: 27 | 28 | 在您的 Nuxt 配置文件中添加 `@unocss/nuxt` : 29 | 30 | ```ts 31 | // nuxt.config.ts 32 | export default defineNuxtConfig({ 33 | modules: ['@unocss/nuxt'] 34 | }) 35 | ``` 36 | 37 | 创建一个 `uno.config.ts` 文件: 38 | 39 | ```ts 40 | // uno.config.ts 41 | import { defineConfig } from 'unocss' 42 | 43 | export default defineConfig({ 44 | // ...UnoCSS 选项 45 | }) 46 | ``` 47 | 48 | `uno.css` 入口将会被模块自动注入。 49 | 50 | ## 支持状态 51 | 52 | | | Nuxt 2 | Nuxt Bridge | Nuxt 3 | 53 | | ------------- | :----- | :---------- | :----- | 54 | | Webpack Dev | ✅ | ✅ | 🚧 | 55 | | Webpack Build | ✅ | ✅ | ✅ | 56 | | Vite Dev | - | ✅ | ✅ | 57 | | Vite Build | - | ✅ | ✅ | 58 | 59 | ## 配置 60 | 61 | 我们建议使用专用的 uno.config.ts 文件进行配置。详见[配置文件](/guide/config-file)了解更多细节。 62 | 63 | ## License 64 | 65 | - MIT License © 2021-PRESENT [Anthony Fu](https://github.com/antfu) 66 | -------------------------------------------------------------------------------- /integrations/postcss.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: UnoCSS PostCSS 插件 3 | outline: deep 4 | --- 5 | 6 | # PostCSS 插件 7 | 8 | UnoCSS 的 PostCSS 插件,支持 `@apply`、`@screen` 和 `theme()` 指令。 9 | 10 | [源码](https://github.com/unocss/unocss/tree/main/packages/postcss) 11 | 12 | ::: warning 13 | 该包目前处于实验状态,不符合语义化版本规范,并且可能在补丁版本中引入破坏性更改。 14 | ::: 15 | 16 | ## Install 17 | 18 | ::: code-group 19 | 20 | ```bash [pnpm] 21 | pnpm add -D @unocss/postcss 22 | ``` 23 | 24 | ```bash [yarn] 25 | yarn add -D @unocss/postcss 26 | ``` 27 | 28 | ```bash [npm] 29 | npm install -D @unocss/postcss 30 | ``` 31 | 32 | ::: 33 | 34 | ```ts 35 | // postcss.config.cjs 36 | module.exports = { 37 | plugins: { 38 | '@unocss/postcss': {} 39 | } 40 | } 41 | ``` 42 | 43 | ```ts 44 | // uno.config.ts 45 | import { defineConfig, presetUno } from 'unocss' 46 | 47 | export default defineConfig({ 48 | content: { 49 | filesystem: ['**/*.{html,js,ts,jsx,tsx,vue,svelte,astro}'] 50 | }, 51 | presets: [presetUno()] 52 | }) 53 | ``` 54 | 55 | ```css 56 | /* style.css */ 57 | @unocss; 58 | ``` 59 | 60 | ## 用法 61 | 62 | ### `@unocss` 63 | 64 | `@unocss` 规则是一个占位符,将被生成的 CSS 替换。 65 | 66 | 您还可以分别注入每个层: 67 | 68 | ```css 69 | /* style.css */ 70 | @unocss preflights; 71 | @unocss default; 72 | 73 | /* 74 | 回退层。始终建议包含。 75 | 只有未使用的层将在此处注入。 76 | */ 77 | @unocss; 78 | ``` 79 | 80 | 如果您想包含所有层,无论它们之前是否已包含,可以使用 @unocss all。这在需要在多个文件中包含生成的 CSS 时非常有用。 81 | 82 | ```css 83 | @unocss all; 84 | ``` 85 | 86 | ### `@apply` 87 | 88 | ```css 89 | .custom-div { 90 | @apply text-center my-0 font-medium; 91 | } 92 | ``` 93 | 94 | 将被转换为: 95 | 96 | ```css 97 | .custom-div { 98 | margin-top: 0rem; 99 | margin-bottom: 0rem; 100 | text-align: center; 101 | font-weight: 500; 102 | } 103 | ``` 104 | 105 | ### `@screen` 106 | 107 | `@screen` 指令允许您创建引用您的断点的媒体查询,断点来自 [`theme.breakpoints`](https://github.com/unocss/unocss/blob/main/README.md#extend-theme)。 108 | 109 | ```css 110 | .grid { 111 | @apply grid grid-cols-2; 112 | } 113 | @screen xs { 114 | .grid { 115 | @apply grid-cols-1; 116 | } 117 | } 118 | @screen sm { 119 | .grid { 120 | @apply grid-cols-3; 121 | } 122 | } 123 | /* ... */ 124 | ... 125 | ``` 126 | 127 | 将被转换为: 128 | 129 | ```css 130 | .grid { 131 | display: grid; 132 | grid-template-columns: repeat(2, minmax(0, 1fr)); 133 | } 134 | @media (min-width: 320px) { 135 | .grid { 136 | grid-template-columns: repeat(1, minmax(0, 1fr)); 137 | } 138 | } 139 | @media (min-width: 640px) { 140 | .grid { 141 | grid-template-columns: repeat(3, minmax(0, 1fr)); 142 | } 143 | } 144 | /* ... */ 145 | ``` 146 | 147 | #### 断点变体支持 148 | 149 | `@screen` 还支持 `lt`、`at` 变体 150 | 151 | ##### `@screen lt` 152 | 153 | ```css 154 | .grid { 155 | @apply grid grid-cols-2; 156 | } 157 | @screen lt-xs { 158 | .grid { 159 | @apply grid-cols-1; 160 | } 161 | } 162 | @screen lt-sm { 163 | .grid { 164 | @apply grid-cols-3; 165 | } 166 | } 167 | /* ... */ 168 | ``` 169 | 170 | 将被转换为: 171 | 172 | ```css 173 | .grid { 174 | display: grid; 175 | grid-template-columns: repeat(2, minmax(0, 1fr)); 176 | } 177 | @media (max-width: 319.9px) { 178 | .grid { 179 | grid-template-columns: repeat(1, minmax(0, 1fr)); 180 | } 181 | } 182 | @media (max-width: 639.9px) { 183 | .grid { 184 | grid-template-columns: repeat(3, minmax(0, 1fr)); 185 | } 186 | } 187 | /* ... */ 188 | ``` 189 | 190 | ##### `@screen at` 191 | 192 | ```css 193 | .grid { 194 | @apply grid grid-cols-2; 195 | } 196 | @screen at-xs { 197 | .grid { 198 | @apply grid-cols-1; 199 | } 200 | } 201 | @screen at-xl { 202 | .grid { 203 | @apply grid-cols-3; 204 | } 205 | } 206 | @screen at-xxl { 207 | .grid { 208 | @apply grid-cols-4; 209 | } 210 | } 211 | /* ... */ 212 | ``` 213 | 214 | 将被转换为: 215 | 216 | ```css 217 | .grid { 218 | display: grid; 219 | grid-template-columns: repeat(2, minmax(0, 1fr)); 220 | } 221 | @media (min-width: 320px) and (max-width: 639.9px) { 222 | .grid { 223 | grid-template-columns: repeat(1, minmax(0, 1fr)); 224 | } 225 | } 226 | @media (min-width: 1280px) and (max-width: 1535.9px) { 227 | .grid { 228 | grid-template-columns: repeat(3, minmax(0, 1fr)); 229 | } 230 | } 231 | @media (min-width: 1536px) { 232 | .grid { 233 | grid-template-columns: repeat(4, minmax(0, 1fr)); 234 | } 235 | } 236 | /* ... */ 237 | ``` 238 | 239 | ### `theme()` 240 | 241 | 使用 `theme()` 函数使用点表示法访问您的主题配置值。 242 | 243 | ```css 244 | .btn-blue { 245 | background-color: theme('colors.blue.500'); 246 | } 247 | ``` 248 | 249 | Will be compiled to: 250 | 251 | ```css 252 | .btn-blue { 253 | background-color: #3b82f6; 254 | } 255 | ``` 256 | -------------------------------------------------------------------------------- /integrations/runtime.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: UnoCSS CDN 运行时 3 | description: CSS-in-JS runtime of UnoCSS (@unocss/runtime). 4 | outline: deep 5 | --- 6 | 7 | # 运行时 8 | 9 | UnoCSS 运行时提供了一个 CDN 构建,可以在浏览器中运行 UnoCSS 引擎。它将检测 DOM 更改并动态生成样式。 10 | 11 | ## 使用方法 12 | 13 | 在您的 `index.html` 文件中添加以下代码: 14 | 15 | ```html 16 | 17 | ``` 18 | 19 | 配置 UnoCSS(可选): 20 | 21 | ```html 22 | 34 | ``` 35 | 36 | 默认情况下,将加载 [Uno 预设](/presets/uno)。 37 | 38 | 运行时不包含预先设置的样式重置。如果您希望有样式重置,您可以添加自己的重置样式,或者使用来自 [Reset 包(/guide/style-reset)] 中的样式重置。 39 | 40 | ```html 41 | 45 | 46 | 50 | ``` 51 | 52 | ## 构建 53 | 54 | 针对不同的用例,提供了多个构建版本。 55 | 56 | ### Core 57 | 58 | 不包含任何预设: 59 | 60 | ```html 61 | 62 | ``` 63 | 64 | ### Uno (默认) 65 | 66 | 包含 `@unocss/preset-uno` 预设: 67 | 68 | ```html 69 | 70 | ``` 71 | 72 | ### Attributify 73 | 74 | 包含 `@unocss/preset-uno` 和 `@unocss/preset-attributify` 预设: 75 | 76 | ```html 77 | 78 | ``` 79 | 80 | ### Mini 81 | 82 | 包含 `@unocss/preset-mini` 和 `@unocss/preset-attributify` 预设: 83 | 84 | ```html 85 | 86 | ``` 87 | 88 | ## 构建器使用方法 89 | 90 | ```bash 91 | npm i @unocss/runtime 92 | ``` 93 | 94 | ```ts 95 | import initUnocssRuntime from '@unocss/runtime' 96 | 97 | initUnocssRuntime({ 98 | /* options */ 99 | }) 100 | ``` 101 | 102 | ## 防止 FOUC 103 | 104 | 由于 UnoCSS 在 DOM 出现后运行,可能会出现 "无样式内容闪烁"(FOUC),导致用户看到页面无样式的情况。 105 | 106 | 使用 `un-cloak` 属性和 CSS 规则,例如 `[un-cloak] { display: none }` 来隐藏无样式的元素,直到 UnoCSS 为它应用样式。 107 | 108 | ```css 109 | [un-cloak] { 110 | display: none; 111 | } 112 | ``` 113 | 114 | ```html 115 |
此文本将仅以蓝色显示。
116 | ``` 117 | -------------------------------------------------------------------------------- /integrations/svelte-scoped.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: UnoCSS Svelte Scoped 3 | description: UnoCSS Svelte Scoped Vite 插件和 UnoCSS 的 Svelte 预处理器。 4 | outline: deep 5 | --- 6 | 7 | # Svelte Scoped 8 | 9 | 将每个 Svelte 组件的实用样式的生成 CSS 直接放入 Svelte 组件的 ` 27 | ``` 28 | 29 | ## 何时使用 30 | 31 | | 使用场景 | | 描述 | 使用的包 | 32 | | -------- | --- | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | 33 | | 小型应用 | :x: | 使用一个全局 CSS 文件更方便。使用常规的 [Svelte](/integrations/vite#svelte)/[SvelteKit](/integrations/vite#sveltekit) Vite 插件。 | [unocss/vite](/integrations/vite#svelte) | 34 | | 大型应用 | ✅ | Svelte Scoped 可以帮助您避免不断增长的全局 CSS 文件。 | [@unocss/svelte-scoped/vite](#vite-plugin) | 35 | | 组件库 | ✅ | 生成的样式直接放置在构建的组件中,而不需要在使用 UnoCSS 的消费应用的构建流程中使用。 | [@unocss/svelte-scoped/preprocess](#svelte-preprocessor) | 36 | 37 | ## 工作原理 38 | 39 | 常规的 UnoCSS/Tailwind 设置将实用样式放在全局 CSS 文件中,并进行适当的排序。相比之下,Svelte Scoped 将样式分布在许多任意顺序的 Svelte 组件 CSS 文件中。但是,它必须保持实用样式的全局性,以便根据需要进行上下文感知,例如适用于从右到左的情况和其他下面列出的[用例](#context-aware)。这带来了一个挑战,使用 Svelte 的 `:global()` 封装器来退出默认的 Svelte CSS 散列方法,而是使用基于文件名 + 类名的散列来编译唯一的类名,可以使其全局化而不会引起样式冲突。 40 | 41 | ## 使用方法 42 | 43 | 由于 Svelte Scoped 会重写您的实用类名,因此您在何处编写它们受到限制: 44 | 45 | | 支持的语法 | 示例 | 46 | | ---------- | -------------------------------- | 47 | | 类属性 | `
` | 48 | | 类指令 | `
` | 49 | | 类指令缩写 | `
` | 50 | | 类 prop | `