主题
Tailwind CSS
Nuxt UI 使用 Tailwind CSS v4,您可以阅读官方升级指南了解所有重大变更。
@theme
Tailwind CSS v4 采用 CSS 优先的配置方法,您现在可以在@theme
指令中通过 CSS 变量自定义主题,定义项目的自定义设计令牌,例如字体、颜色和断点。
@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 自动内容检测无法识别的源文件。
这在编写 Markdown 文件中的 Tailwind CSS 类时很有用,例如结合使用@nuxt/content
。
@import "tailwindcss";
@import "@nuxt/ui";
@source "../../../content";
/* Use this if you're not using compatibilityVersion: 4: https://nuxtjs.org.cn/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://nuxtjs.org.cn/docs/getting-started/upgrade#opting-in-to-nuxt-4 */
@source "../../content";
设计系统
Nuxt UI 扩展了 Tailwind CSS 的主题功能,提供了一个灵活的设计系统,其中包含基于Tailwind CSS 颜色的预配置颜色别名。这使得轻松自定义和快速调整 UI 以符合您的品牌美学成为可能。
颜色 | 默认值 | 描述 |
---|---|---|
primary | green | 主要品牌色,用作组件的默认颜色。 |
secondary | blue | 辅助颜色,用于补充主要颜色。 |
success | green | 用于成功状态。 |
info | blue | 用于信息状态。 |
warning | yellow | 用于警告状态。 |
error | red | 用于表单验证错误状态。 |
neutral | slate | 中性色,用于背景、文本等。 |
这些颜色用于组件的样式设置,也用于生成 color
props。
<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/ui/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
中添加自己的动态颜色别名,但必须确保同时在 ui.theme.colors
选项中定义它们在您的 nuxt.config.ts
文件。
export default defineAppConfig({
ui: {
colors: {
tertiary: 'indigo'
}
}
})
export default defineNuxtConfig({
ui: {
theme: {
colors: [
'primary',
'secondary',
'tertiary',
'info',
'success',
'warning',
'error'
]
}
}
})
您可以在 vite.config.ts
中添加自己的动态颜色别名,但必须确保同时在 theme.colors
选项中定义它们在 ui
插件。
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/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
文件中覆盖 primary 颜色以创建黑白主题。
您不能在您的vite.config.ts
中设置 primary: 'black'
,因为此颜色没有色调。相反,您可以在 main.css
文件中覆盖 primary 颜色以创建黑白主题。
@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);
--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);
--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);
--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;
}
Container
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 VariantsAPI 进行样式设置,该 API 提供了创建变体和管理组件样式的强大方法。让我们探讨一下此 API 的主要特性。
插槽
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.class, props.ui?.root] })">
<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-(--ui-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
根据 prop 改变 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
prop 将把相应的样式应用到 root
插槽。
<template>
<UAvatar src="https://github.com/nuxt.png" size="lg" />
</template>
defaultVariants
属性指定了每个变体的默认值。它决定了组件在未提供 prop 时的外观和行为。
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/ui/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
prop 覆盖组件的 插槽。这优先于全局配置和 variants
解析。
<template>
<UButton
trailing-icon="i-lucide-chevron-right"
size="md"
color="neutral"
variant="outline"
:ui="{
trailingIcon: 'rotate-90 size-3'
}"
>
Button
</UButton>
</template>
md
尺寸变体本应向 trailingIcon
插槽应用 size-5
类,它也被 size-3
覆盖。class
prop
class
prop 允许您覆盖 root
或 base
插槽的类。这优先于全局配置和 variants
解析。
<template>
<UButton class="font-bold rounded-full">Button</UButton>
</template>
font-bold
类将覆盖此按钮默认的 font-medium
类。