Theme
Tailwind CSS
Nuxt UI v3 uses Tailwind CSS v4 alpha which doesn't have a documentation yet, let's have a look on how to use it.
@theme
Tailwind CSS v4 takes a CSS-first configuration approach, you now customize your theme with CSS variables inside a @theme
directive:
@import "tailwindcss";
@import "@nuxt/ui";
@theme {
--font-family-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;
}
The @theme
directive tells Tailwind to make new utilities and variants available based on those variables. It's the equivalent of the theme.extend
key in Tailwind CSS v3 tailwind.config.ts
file.
This is exactly what the @import "@nuxt/ui";
is all about, it extends the default Tailwind CSS theme and declares the primary
, error
and gray
colors to be configurable through the App Config but we'll talk more about that in the Colors section.
@source
You can use the @source
directive to add explicit content glob patterns if you want to look for Tailwind classes in other files that are not automatically detected.
This can be useful when writing Tailwind classes in markdown files with @nuxt/content
:
@import "tailwindcss";
@import "@nuxt/ui";
@source "../content/**/*.md";
@plugin
You can use the @plugin
directive to import Tailwind CSS plugins.
@import "tailwindcss";
@import "@nuxt/ui";
@plugin "@tailwindcss/typography";
Tailwind Variants API
Nuxt UI components are styled using the Tailwind Variants API, which provides a powerful way to create variants and manage component styles. Let's explore the key features of this API:
Slots
Components in Nuxt UI can have multiple slots
, each representing a distinct HTML element or section within the component. These slots allow for flexible content insertion and styling. Let's take the Card component as an example:
export default {
slots: {
root: 'bg-white dark:bg-gray-900 ring ring-gray-200 dark:ring-gray-800 divide-y divide-gray-200 dark:divide-gray-800 rounded-lg shadow',
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>
Some components don't have slots, they are just composed of a single root element. In this case, the theme only defines the base
slot like the Container component for example:
export default {
base: 'max-w-7xl mx-auto px-4 sm:px-6 lg:px-8'
}
<template>
<div :class="container({ class: props.class })">
<slot />
</div>
</template>
ui
prop, only the class
prop is available to override styles.Variants
Nuxt UI components use variants
to change the slots
styles based on props. Here's an example of the Avatar component:
export default {
slots: {
root: 'inline-flex items-center justify-center shrink-0 select-none overflow-hidden rounded-full align-middle bg-gray-100 dark:bg-gray-800',
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'
}
}
This way, the size
prop will apply the corresponding styles to the root
slot:
<template>
<UAvatar src="https://github.com/benjamincanac.png" size="lg" />
</template>
The defaultVariants
property specifies the default values for each variant. It determines how a component looks and behaves when no prop is provided. These default values can be customized in your app.config.ts
to adjust the standard appearance of components throughout your application.
Customize components
You have multiple ways to customize the appearance of Nuxt UI components, you can do it for all components at once or on a per-component basis.
- Check the
Theme
section in the documentation of each individual component. - Browse the source code directly in the GitHub repository at https://github.com/nuxt/ui/tree/v3/src/theme.
app.config.ts
You can override the theme of components inside your app.config.ts
by using the exact same structure as the theme object.
Let's say you want to change the font weight of all your buttons, you can do it like this:
export default defineAppConfig({
ui: {
button: {
slots: {
base: 'font-bold'
}
}
}
})
In this example, the font-bold
class will override the default font-medium
class on all buttons.
ui
prop
You can also override a component's slots using the ui
prop. This has priority over the app.config.ts
configuration and variants
resolution.
<template>
<UButton
icon="i-heroicons-magnifying-glass"
color="gray"
variant="outline"
:ui="{
leadingIcon: 'text-primary-500 dark:text-primary-400 size-3'
}"
>
Button
</UButton>
</template>
In this example, the leadingIcon
slot is overwritten even though the md
size variant would apply a size-5
class by default.
class
prop
The class
prop allows you to override the classes of the root
or base
slot. This has priority over the app.config.ts
configuration and variants
resolution.
<template>
<UButton class="font-bold rounded-full">Button</UButton>
</template>