主题
Tailwind CSS
Nuxt UI 使用 Tailwind CSS v4,您可以阅读官方 升级指南 以了解所有重大更改。
@theme
Tailwind CSS v4 采用 CSS 优先的配置方法,您现在可以使用 CSS 变量在 @theme 指令中自定义您的主题,以定义您项目的自定义设计令牌,例如字体、颜色和断点:
@import "tailwindcss";
@import "@nuxt/ui";
@theme static {
--font-sans: 'Public Sans', sans-serif;
--breakpoint-3xl: 1920px;
--color-green-50: #EFFDF5;
--color-green-100: #D9FBE8;
--color-green-200: #B3F5D1;
--color-green-300: #75EDAE;
--color-green-400: #00DC82;
--color-green-500: #00C16A;
--color-green-600: #00A155;
--color-green-700: #007F45;
--color-green-800: #016538;
--color-green-900: #0A5331;
--color-green-950: #052E16;
}
@import "tailwindcss";
@import "@nuxt/ui-pro";
@theme static {
--font-sans: 'Public Sans', sans-serif;
--breakpoint-3xl: 1920px;
--color-green-50: #EFFDF5;
--color-green-100: #D9FBE8;
--color-green-200: #B3F5D1;
--color-green-300: #75EDAE;
--color-green-400: #00DC82;
--color-green-500: #00C16A;
--color-green-600: #00A155;
--color-green-700: #007F45;
--color-green-800: #016538;
--color-green-900: #0A5331;
--color-green-950: #052E16;
}
@theme 指令告诉 Tailwind 根据这些变量提供新的实用工具和变体。它相当于 Tailwind CSS v3 tailwind.config.ts 文件中的 theme.extend 键。
@source
您可以使用 @source 指令 来明确指定未被 Tailwind 自动内容检测识别的源文件:
这在例如使用 @nuxt/content 在 markdown 文件中编写 Tailwind CSS 类时很有用:
@import "tailwindcss";
@import "@nuxt/ui";
@source "../../../content";
/* Use this if you're not using compatibilityVersion: 4: https://nuxt.com/docs/getting-started/upgrade#opting-in-to-nuxt-4 */
@source "../../content";
@import "tailwindcss";
@import "@nuxt/ui-pro";
@source "../../../content";
/* Use this if you're not using compatibilityVersion: 4: https://nuxt.com/docs/getting-started/upgrade#opting-in-to-nuxt-4 */
@source "../../content";
设计系统
Nuxt UI 扩展了 Tailwind CSS 的主题功能,提供了一个灵活的设计系统,其中包含基于 Tailwind CSS 颜色 的预配置颜色别名。这使得可以轻松自定义 UI 并快速将 UI 适应您品牌的审美。
| 颜色 | 默认值 | 描述 |
|---|---|---|
primary | green | 主要品牌颜色,用作组件的默认颜色。 |
secondary | blue | 辅助颜色以补充主要颜色。 |
success | green | 用于成功状态。 |
info | blue | 用于信息状态。 |
warning | yellow | 用于警告状态。 |
error | red | 用于表单错误验证状态。 |
neutral | slate | 背景、文本等的中性颜色。 |
这些颜色用于样式化组件,也用于生成 color 属性:
<template>
<UButton color="primary">Button</UButton>
</template>
primary 和 neutral 颜色。配置
您可以在 app.config.ts 文件中在 ui.colors 键下运行时配置这些颜色别名,从而实现动态主题定制,而无需重新构建应用程序:
export default defineAppConfig({
ui: {
colors: {
primary: 'blue',
neutral: 'zinc'
}
}
})
您可以在 vite.config.ts 文件中在 ui.colors 键下运行时配置这些颜色别名:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/content/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
colors: {
primary: 'blue',
neutral: 'zinc'
}
}
})
]
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import uiPro from '@nuxt/ui-pro/vite'
export default defineConfig({
plugins: [
vue(),
uiPro({
ui: {
colors: {
primary: 'blue',
neutral: 'zinc'
}
}
})
]
})
扩展颜色
您可以在 app.config.ts 中添加自己的动态颜色别名,您只需确保在 nuxt.config.ts 文件中的 ui.theme.colors 选项中定义它们:
export default defineAppConfig({
ui: {
colors: {
tertiary: 'indigo'
}
}
})
export default defineNuxtConfig({
ui: {
theme: {
colors: [
'primary',
'secondary',
'tertiary',
'info',
'success',
'warning',
'error'
]
}
}
})
您可以在 vite.config.ts 中添加自己的动态颜色别名,您只需确保同时在 ui 插件的 theme.colors 选项中定义它们:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/content/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
colors: {
tertiary: 'indigo'
}
},
theme: {
colors: [
'primary',
'secondary',
'tertiary',
'info',
'success',
'warning',
'error'
]
}
})
]
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import uiPro from '@nuxt/ui-pro/vite'
export default defineConfig({
plugins: [
vue(),
uiPro({
ui: {
colors: {
tertiary: 'indigo'
}
},
theme: {
colors: [
'primary',
'secondary',
'tertiary',
'info',
'success',
'warning',
'error'
]
}
})
]
})
CSS 变量
Nuxt UI 利用强大的 CSS 变量系统作为设计令牌,以确保一致且灵活的组件样式。这些令牌构成了主题系统的基础,为浅色和深色模式提供了流畅的支持。
颜色
Nuxt UI 为您定义的每个颜色别名提供一个 CSS 变量,该变量表示浅色和深色模式中使用的默认色调:
:root {
--ui-primary: var(--ui-color-primary-500);
--ui-secondary: var(--ui-color-secondary-500);
--ui-success: var(--ui-color-success-500);
--ui-info: var(--ui-color-info-500);
--ui-warning: var(--ui-color-warning-500);
--ui-error: var(--ui-color-error-500);
}
.dark {
--ui-primary: var(--ui-color-primary-400);
--ui-secondary: var(--ui-color-secondary-400);
--ui-success: var(--ui-color-success-400);
--ui-info: var(--ui-color-info-400);
--ui-warning: var(--ui-color-warning-400);
--ui-error: var(--ui-color-error-400);
}
这些 CSS 变量在 Tailwind CSS 的 @theme 中定义,因此您可以将它们用作类:
PrimarySecondarySuccessInfoWarningError
<template>
<span class="text-primary">Primary</span>
<span class="text-secondary">Secondary</span>
<span class="text-success">Success</span>
<span class="text-info">Info</span>
<span class="text-warning">Warning</span>
<span class="text-error">Error</span>
</template>
@theme 生成方式如下:@theme default {
--color-primary: var(--ui-primary);
--color-primary-50: var(--ui-color-primary-50);
--color-primary-100: var(--ui-color-primary-100);
--color-primary-200: var(--ui-color-primary-200);
--color-primary-300: var(--ui-color-primary-300);
--color-primary-400: var(--ui-color-primary-400);
--color-primary-500: var(--ui-color-primary-500);
--color-primary-600: var(--ui-color-primary-600);
--color-primary-700: var(--ui-color-primary-700);
--color-primary-800: var(--ui-color-primary-800);
--color-primary-900: var(--ui-color-primary-900);
--color-primary-950: var(--ui-color-primary-950);
--color-secondary: var(--ui-secondary);
--color-secondary-50: var(--ui-color-secondary-50);
--color-secondary-100: var(--ui-color-secondary-100);
--color-secondary-200: var(--ui-color-secondary-200);
--color-secondary-300: var(--ui-color-secondary-300);
--color-secondary-400: var(--ui-color-secondary-400);
--color-secondary-500: var(--ui-color-secondary-500);
--color-secondary-600: var(--ui-color-secondary-600);
--color-secondary-700: var(--ui-color-secondary-700);
--color-secondary-800: var(--ui-color-secondary-800);
--color-secondary-900: var(--ui-color-secondary-900);
--color-secondary-950: var(--ui-color-secondary-950);
--color-success: var(--ui-success);
--color-success-50: var(--ui-color-success-50);
--color-success-100: var(--ui-color-success-100);
--color-success-200: var(--ui-color-success-200);
--color-success-300: var(--ui-color-success-300);
--color-success-400: var(--ui-color-success-400);
--color-success-500: var(--ui-color-success-500);
--color-success-600: var(--ui-color-success-600);
--color-success-700: var(--ui-color-success-700);
--color-success-800: var(--ui-color-success-800);
--color-success-900: var(--ui-color-success-900);
--color-success-950: var(--ui-color-success-950);
--color-info: var(--ui-info);
--color-info-50: var(--ui-color-info-50);
--color-info-100: var(--ui-color-info-100);
--color-info-200: var(--ui-color-info-200);
--color-info-300: var(--ui-color-info-300);
--color-info-400: var(--ui-color-info-400);
--color-info-500: var(--ui-color-info-500);
--color-info-600: var(--ui-color-info-600);
--color-info-700: var(--ui-color-info-700);
--color-info-800: var(--ui-color-info-800);
--color-info-900: var(--ui-color-info-900);
--color-info-950: var(--ui-color-info-950);
--color-warning: var(--ui-warning);
--color-warning-50: var(--ui-color-warning-50);
--color-warning-100: var(--ui-color-warning-100);
--color-warning-200: var(--ui-color-warning-200);
--color-warning-300: var(--ui-color-warning-300);
--color-warning-400: var(--ui-color-warning-400);
--color-warning-500: var(--ui-color-warning-500);
--color-warning-600: var(--ui-color-warning-600);
--color-warning-700: var(--ui-color-warning-700);
--color-warning-800: var(--ui-color-warning-800);
--color-warning-900: var(--ui-color-warning-900);
--color-warning-950: var(--ui-color-warning-950);
--color-error: var(--ui-error);
--color-error-50: var(--ui-color-error-50);
--color-error-100: var(--ui-color-error-100);
--color-error-200: var(--ui-color-error-200);
--color-error-300: var(--ui-color-error-300);
--color-error-400: var(--ui-color-error-400);
--color-error-500: var(--ui-color-error-500);
--color-error-600: var(--ui-color-error-600);
--color-error-700: var(--ui-color-error-700);
--color-error-800: var(--ui-color-error-800);
--color-error-900: var(--ui-color-error-900);
--color-error-950: var(--ui-color-error-950);
--color-neutral-50: var(--ui-color-neutral-50);
--color-neutral-100: var(--ui-color-neutral-100);
--color-neutral-200: var(--ui-color-neutral-200);
--color-neutral-300: var(--ui-color-neutral-300);
--color-neutral-400: var(--ui-color-neutral-400);
--color-neutral-500: var(--ui-color-neutral-500);
--color-neutral-600: var(--ui-color-neutral-600);
--color-neutral-700: var(--ui-color-neutral-700);
--color-neutral-800: var(--ui-color-neutral-800);
--color-neutral-900: var(--ui-color-neutral-900);
--color-neutral-950: var(--ui-color-neutral-950);
}
您可以在 main.css 文件中更改浅色和深色模式下每种颜色使用的色调:
@import "tailwindcss";
@import "@nuxt/ui";
:root {
--ui-primary: var(--ui-color-primary-700);
}
.dark {
--ui-primary: var(--ui-color-primary-200);
}
@import "tailwindcss";
@import "@nuxt/ui-pro";
:root {
--ui-primary: var(--ui-color-primary-700);
}
.dark {
--ui-primary: var(--ui-color-primary-200);
}
您不能在 app.config.ts 中设置 primary: 'black',因为此颜色没有色调,相反,您可以在 main.css 文件中覆盖主色以创建黑白主题:
您不能在 vite.config.ts 中设置 primary: 'black',因为此颜色没有色调,相反,您可以在 main.css 文件中覆盖主色以创建黑白主题:
@import "tailwindcss";
@import "@nuxt/ui";
:root {
--ui-primary: black;
}
.dark {
--ui-primary: white;
}
@import "tailwindcss";
@import "@nuxt/ui-pro";
:root {
--ui-primary: black;
}
.dark {
--ui-primary: white;
}
中性色板
Nuxt UI 为 neutral 调色板提供了一套全面的设计令牌,确保在浅色和深色模式下实现一致且可访问的 UI 样式。这些令牌对文本、背景和边框颜色提供精细控制:
:root {
--ui-text-dimmed: var(--ui-color-neutral-400);
--ui-text-muted: var(--ui-color-neutral-500);
--ui-text-toned: var(--ui-color-neutral-600);
--ui-text: var(--ui-color-neutral-700);
--ui-text-highlighted: var(--ui-color-neutral-900);
--ui-text-inverted: var(--color-white);
--ui-bg: var(--color-white);
--ui-bg-muted: var(--ui-color-neutral-50);
--ui-bg-elevated: var(--ui-color-neutral-100);
--ui-bg-accented: var(--ui-color-neutral-200);
--ui-bg-inverted: var(--ui-color-neutral-900);
--ui-border: var(--ui-color-neutral-200);
--ui-border-muted: var(--ui-color-neutral-200);
--ui-border-accented: var(--ui-color-neutral-300);
--ui-border-inverted: var(--ui-color-neutral-900);
}
.dark {
--ui-text-dimmed: var(--ui-color-neutral-500);
--ui-text-muted: var(--ui-color-neutral-400);
--ui-text-toned: var(--ui-color-neutral-300);
--ui-text: var(--ui-color-neutral-200);
--ui-text-highlighted: var(--color-white);
--ui-text-inverted: var(--ui-color-neutral-900);
--ui-bg: var(--ui-color-neutral-900);
--ui-bg-muted: var(--ui-color-neutral-800);
--ui-bg-elevated: var(--ui-color-neutral-800);
--ui-bg-accented: var(--ui-color-neutral-700);
--ui-bg-inverted: var(--color-white);
--ui-border: var(--ui-color-neutral-800);
--ui-border-muted: var(--ui-color-neutral-700);
--ui-border-accented: var(--ui-color-neutral-700);
--ui-border-inverted: var(--color-white);
}
这些 CSS 变量在 Tailwind CSS 的 @theme 中定义,因此您可以将它们用作类:
DimmedMutedTonedTextHighlightedInverted
<template>
<span class="text-dimmed">Dimmed</span>
<span class="text-muted">Muted</span>
<span class="text-toned">Toned</span>
<span class="text-default">Text</span>
<span class="text-highlighted">Highlighted</span>
<span class="text-inverted bg-inverted">Inverted</span>
</template>
DefaultMutedElevatedAccentedInverted
<template>
<div class="bg-default">Default</div>
<div class="bg-muted">Muted</div>
<div class="bg-elevated">Elevated</div>
<div class="bg-accented">Accented</div>
<div class="bg-inverted text-inverted">Inverted</div>
</template>
DefaultMutedAccentedInverted
<template>
<div class="border border-default">Default</div>
<div class="border border-muted">Muted</div>
<div class="border border-accented">Accented</div>
<div class="border border-inverted">Inverted</div>
</template>
@theme 生成方式如下:@theme default {
--text-color-dimmed: var(--ui-text-dimmed);
--text-color-muted: var(--ui-text-muted);
--text-color-toned: var(--ui-text-toned);
--text-color-default: var(--ui-text);
--text-color-highlighted: var(--ui-text-highlighted);
--text-color-inverted: var(--ui-text-inverted);
--background-color-default: var(--ui-bg);
--background-color-muted: var(--ui-bg-muted);
--background-color-elevated: var(--ui-bg-elevated);
--background-color-accented: var(--ui-bg-accented);
--background-color-inverted: var(--ui-bg-inverted);
--background-color-border: var(--ui-border);
--border-color-default: var(--ui-border);
--border-color-muted: var(--ui-border-muted);
--border-color-accented: var(--ui-border-accented);
--border-color-inverted: var(--ui-border-inverted);
--border-color-bg: var(--ui-bg);
--ring-color-default: var(--ui-border);
--ring-color-muted: var(--ui-border-muted);
--ring-color-accented: var(--ui-border-accented);
--ring-color-inverted: var(--ui-border-inverted);
--ring-color-bg: var(--ui-bg);
--ring-offset-color-default: var(--ui-border);
--ring-offset-color-muted: var(--ui-border-muted);
--ring-offset-color-accented: var(--ui-border-accented);
--ring-offset-color-inverted: var(--ui-border-inverted);
--ring-offset-color-bg: var(--ui-bg);
--divide-color-default: var(--ui-border);
--divide-color-muted: var(--ui-border-muted);
--divide-color-accented: var(--ui-border-accented);
--divide-color-inverted: var(--ui-border-inverted);
--divide-color-bg: var(--ui-bg);
--outline-color-default: var(--ui-border);
--outline-color-inverted: var(--ui-border-inverted);
--stroke-color-default: var(--ui-border);
--stroke-color-inverted: var(--ui-border-inverted);
--fill-color-default: var(--ui-border);
--fill-color-inverted: var(--ui-border-inverted);
}
您可以在 main.css 文件中自定义这些 CSS 变量,以调整应用程序的外观:
@import "tailwindcss";
@import "@nuxt/ui";
:root {
--ui-bg: var(--ui-color-neutral-50);
--ui-text: var(--ui-color-neutral-900);
}
.dark {
--ui-bg: var(--ui-color-neutral-950);
--ui-border: var(--ui-color-neutral-900);
}
@import "tailwindcss";
@import "@nuxt/ui-pro";
:root {
--ui-bg: var(--ui-color-neutral-50);
--ui-text: var(--ui-color-neutral-900);
}
.dark {
--ui-bg: var(--ui-color-neutral-950);
--ui-border: var(--ui-color-neutral-900);
}
<body> 元素上应用文本和背景颜色:body {
@apply antialiased text-default bg-default scheme-light dark:scheme-dark;
}
圆角
Nuxt UI 通过 --ui-radius CSS 变量提供了一个集中的边框圆角系统。
:root {
--ui-radius: 0.25rem;
}
此 CSS 变量取代了 Tailwind CSS 的默认 rounded-* 实用程序,因此您可以使用相同的类名:
xssmmdlgxl2xl3xl
<template>
<div class="rounded-xs">xs</div>
<div class="rounded-sm">sm</div>
<div class="rounded-md">md</div>
<div class="rounded-lg">lg</div>
<div class="rounded-xl">xl</div>
<div class="rounded-2xl">2xl</div>
<div class="rounded-3xl">3xl</div>
</template>
@theme 生成方式如下:@theme default {
--radius-xs: calc(var(--ui-radius) * 0.5); /* 0.125rem */
--radius-sm: var(--ui-radius); /* 0.25rem */
--radius-md: calc(var(--ui-radius) * 1.5); /* 0.375rem */
--radius-lg: calc(var(--ui-radius) * 2); /* 0.5rem */
--radius-xl: calc(var(--ui-radius) * 3); /* 0.75rem */
--radius-2xl: calc(var(--ui-radius) * 4); /* 1rem */
--radius-3xl: calc(var(--ui-radius) * 6); /* 1.5rem */
}
您可以在 main.css 文件中自定义基本圆角值:
@import "tailwindcss";
@import "@nuxt/ui";
:root {
--ui-radius: 0.5rem;
}
@import "tailwindcss";
@import "@nuxt/ui-pro";
:root {
--ui-radius: 0.5rem;
}
容器
Nuxt UI 提供了一个 --ui-container CSS 变量,用于控制 Container 组件的最大宽度。
:root {
--ui-container: var(--container-7xl);
}
您可以在 main.css 文件中自定义此值,以在整个应用程序中一致地调整容器宽度:
@import "tailwindcss";
@import "@nuxt/ui";
@theme {
--container-8xl: 90rem;
}
:root {
--ui-container: var(--container-8xl);
}
@import "tailwindcss";
@import "@nuxt/ui-pro";
@theme {
--container-8xl: 90rem;
}
:root {
--ui-container: var(--container-8xl);
}
组件主题
Nuxt UI 组件使用 Tailwind Variants API 进行样式设置,这提供了一种创建变体和管理组件样式的强大方式。让我们探索此 API 的主要功能:
Slots
Nuxt UI 中的组件可以有多个 slots,每个插槽代表组件内的一个独立 HTML 元素或部分。这些插槽允许灵活的内容插入和样式设置。以 Card 组件为例:
export default {
slots: {
root: 'bg-default ring ring-default divide-y divide-default rounded-lg',
header: 'p-4 sm:px-6',
body: 'p-4 sm:p-6',
footer: 'p-4 sm:px-6'
}
}
<template>
<div :class="ui.root({ class: [props.ui?.root, props.class] })">
<div :class="ui.header({ class: props.ui?.header })">
<slot name="header" />
</div>
<div :class="ui.body({ class: props.ui?.body })">
<slot />
</div>
<div :class="ui.footer({ class: props.ui?.footer })">
<slot name="footer" />
</div>
</div>
</template>
有些组件没有插槽,它们只由一个根元素组成。在这种情况下,主题只定义 base 插槽,例如 Container 组件:
export default {
base: 'max-w-(--content-container) mx-auto px-4 sm:px-6 lg:px-8'
}
<template>
<div :class="container({ class: props.class })">
<slot />
</div>
</template>
ui prop,只有 class prop 可用于覆盖样式。变体
Nuxt UI 组件使用 variants 根据属性更改 slots 样式。以下是 Avatar 组件的示例:
export default {
slots: {
root: 'inline-flex items-center justify-center shrink-0 select-none overflow-hidden rounded-full align-middle bg-elevated',
image: 'h-full w-full rounded-[inherit] object-cover'
},
variants: {
size: {
sm: {
root: 'size-7 text-sm'
},
md: {
root: 'size-8 text-base'
},
lg: {
root: 'size-9 text-lg'
}
}
},
defaultVariants: {
size: 'md'
}
}
这样,size 属性将把相应的样式应用到 root 插槽:
<template>
<UAvatar src="https://github.com/nuxt.png" size="lg" />
</template>
defaultVariants 属性指定每个变体的默认值。它决定了在未提供属性时组件的外观和行为。
app.config.ts 中自定义,以调整应用程序中组件的标准外观。vite.config.ts 中自定义,以调整应用程序中组件的标准外观。自定义主题
您可以通过多种方式自定义 Nuxt UI 组件的外观,可以一次性为所有组件进行自定义,也可以按组件进行自定义。
tailwind-merge 来合并类,因此您不必担心类冲突。- 查看每个独立组件文档中的
Theme部分。 - 直接在 GitHub 存储库的
v3/src/theme中浏览源代码。
配置
您可以使用与主题对象完全相同的结构,在 app.config.ts 中全局覆盖组件主题。
例如,如果您想更改所有按钮的字体粗细,可以这样做:
export default defineAppConfig({
ui: {
button: {
slots: {
base: 'font-bold'
}
}
}
})
您可以使用与主题对象完全相同的结构,在 vite.config.ts 中全局覆盖组件主题。
例如,如果您想更改所有按钮的字体粗细,可以这样做:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/content/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
button: {
slots: {
base: 'font-bold'
}
}
}
})
]
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import uiPro from '@nuxt/ui-pro/vite'
export default defineConfig({
plugins: [
vue(),
uiPro({
ui: {
button: {
slots: {
base: 'font-bold'
}
}
}
})
]
})
font-bold 类将覆盖所有按钮上的默认 font-medium 类。Props
ui prop
您还可以使用 ui 属性覆盖组件的 插槽。这优先于全局配置和 variants 解析。
<template>
<UButton
trailing-icon="i-lucide-chevron-right"
size="md"
color="neutral"
variant="outline"
:ui="{
trailingIcon: 'rotate-90 size-3'
}"
>
Button
</UButton>
</template>
trailingIcon 插槽被 size-3 覆盖,尽管 md 大小变体也会对其应用 size-5 类。class prop
class prop 允许您覆盖 root 或 base 插槽的类。这优先于全局配置和 variants 解析。
<template>
<UButton class="font-bold rounded-full">Button</UButton>
</template>
font-bold 类将覆盖此按钮上的默认 font-medium 类。