--- title: Theme description: 'Learn to customize Nuxt UI components using Tailwind CSS v4 and the Tailwind Variants API.' --- ## Tailwind CSS Since 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. Tailwind CSS v4 takes a CSS-first configuration approach, you now customize your theme with CSS variables inside a `@theme` directive: ```css [main.css] @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. ::note You can learn more about this on [https://tailwindcss.com/blog/tailwindcss-v4-alpha](https://tailwindcss.com/blog/tailwindcss-v4-alpha#css-first-configuration). :: This is exactly what the [`@import "@nuxt/ui";`](https://github.com/nuxt/ui/blob/v3/src/runtime/index.css) 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](https://nuxt.com/docs/guide/directory-structure/app-config#app-config-file) but we'll talk more about that in the [Colors](/getting-started/colors) section. ## Tailwind Variants API Nuxt UI components are styled using the [Tailwind Variants](https://www.tailwind-variants.org/) 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](/components/card) component as an example: ::code-group ```ts [src/theme/card.ts] 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' } } ``` ```vue [src/runtime/components/Card.vue] ``` :: 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](/components/container) component for example: ::code-group ```ts [src/theme/container.ts] export default { base: 'max-w-7xl mx-auto px-4 sm:px-6 lg:px-8' } ``` ```vue [src/runtime/components/Container.vue] ``` :: ::caution Components without slots don't have a [`ui` prop](#ui-prop), only the [`class` prop](#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](/components/avatar) component: ```ts [src/theme/avatar.ts] 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: ::component-code{slug="avatar"} --- ignore: - src props: src: 'https://github.com/benjamincanac.png' size: lg --- :: 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`](#appconfigts) 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. ::tip Tailwind Variants uses [tailwind-merge](https://github.com/dcastil/tailwind-merge) under the hood to merge classes so you don't have to worry about conflicting classes. :: ::note You can explore the theme for each component in two ways: - 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: ```ts [app.config.ts] 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. ::component-code{slug="button"} --- prettier: true ignore: - ui.leadingIcon - color - variant - size - icon props: icon: i-heroicons-magnifying-glass size: md color: gray variant: outline ui: leadingIcon: 'text-primary-500 dark:text-primary-400 size-3' slots: default: | Button --- :: 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. ::component-code{slug="button"} --- props: class: 'font-bold rounded-full' slots: default: Button --- ::