Styling

Learn about Tailwind CSS v4 and theming in this boilerplate

This boilerplate uses Tailwind CSS v4 for styling, providing a utility-first approach with excellent developer experience and built-in dark mode support.

Overview

The styling system includes:

  • Tailwind CSS v4 - Latest version with improved performance
  • Dark/light mode - Automatic theme switching with system preference detection
  • Custom design tokens - Centralized color and spacing configuration
  • Typography plugin - Beautiful prose styles for content
  • Auto-complete - Full IntelliSense support in your editor

Configuration

Tailwind configuration

The main Tailwind CSS file is located at app/assets/css/tailwind.css:

app/assets/css/tailwind.css
@import 'tailwindcss';

/* Your custom styles here */

Nuxt configuration

Tailwind is integrated via the Vite plugin in nuxt.config.ts:

nuxt.config.ts
import tailwindcss from '@tailwindcss/vite'

export default defineNuxtConfig({
  css: ['~/assets/css/tailwind.css'],
  vite: {
    plugins: [tailwindcss()],
  },
})

Dark mode

Dark mode is implemented using @nuxtjs/color-mode with Tailwind's dark mode support.

Color mode configuration

nuxt.config.ts
export default defineNuxtConfig({
  colorMode: {
    preference: 'system', // system, dark, or light
    classSuffix: '', // Empty for Tailwind compatibility
  },
})

Using dark mode in components

Tailwind's dark: variant applies styles in dark mode:

<template>
  <div class="bg-white dark:bg-black text-black dark:text-white">This adapts to the theme</div>
</template>

Theme switcher

The boilerplate includes a theme switcher component at app/components/header/ThemeSwitcher.vue:

<script setup>
const colorMode = useColorMode()

const setTheme = theme => {
  colorMode.preference = theme
}
</script>

<template>
  <DropdownMenu>
    <DropdownMenuItem @click="setTheme('light')"> Light </DropdownMenuItem>
    <DropdownMenuItem @click="setTheme('dark')"> Dark </DropdownMenuItem>
    <DropdownMenuItem @click="setTheme('system')"> System </DropdownMenuItem>
  </DropdownMenu>
</template>

Accessing color mode in script

<script setup>
const colorMode = useColorMode()

// Get current theme
console.log(colorMode.value) // 'light', 'dark', or 'system'

// Check if dark mode is active
const isDark = computed(() => colorMode.value === 'dark')

// Set theme
colorMode.preference = 'dark'
</script>

Design system

The boilerplate uses CSS variables for theming, defined in app/assets/css/tailwind.css:

app/assets/css/tailwind.css
@theme {
  /* Color palette */
  --color-background: 0 0% 100%;
  --color-foreground: 240 10% 3.9%;
  --color-primary: 240 5.9% 10%;
  --color-muted: 240 4.8% 95.9%;

  /* Dark mode colors */
  @dark {
    --color-background: 240 10% 3.9%;
    --color-foreground: 0 0% 98%;
    --color-primary: 0 0% 98%;
    --color-muted: 240 3.7% 15.9%;
  }
}

Using design tokens

<template>
  <div class="bg-background text-foreground">
    <h1 class="text-primary">Title</h1>
    <p class="text-muted-foreground">Description</p>
  </div>
</template>

Common utility classes

Layout

<!-- Flexbox -->
<div class="flex items-center justify-between gap-4">
  <!-- Grid -->
  <div class="grid grid-cols-3 gap-4">
    <!-- Container with max width -->
    <div class="base-container"><!-- Custom class defined in the boilerplate --></div>
  </div>
</div>

Spacing

<!-- Padding -->
<div class="p-4">
  <!-- All sides -->
  <div class="px-4 py-8">
    <!-- Horizontal and vertical -->

    <!-- Margin -->
    <div class="m-4">
      <!-- All sides -->
      <div class="mb-8">
        <!-- Bottom only -->

        <!-- Gap -->
        <div class="flex gap-4"><!-- Space between flex items --></div>
      </div>
    </div>
  </div>
</div>

Typography

<!-- Font size -->
<h1 class="text-4xl font-bold">Heading</h1>
<p class="text-base">Body text</p>
<span class="text-sm text-muted-foreground">Caption</span>

<!-- Font weight -->
<span class="font-light">Light</span>
<span class="font-normal">Normal</span>
<span class="font-semibold">Semibold</span>
<span class="font-bold">Bold</span>

Colors

<!-- Text colors -->
<p class="text-foreground">Primary text</p>
<p class="text-muted-foreground">Secondary text</p>
<p class="text-destructive">Error text</p>

<!-- Background colors -->
<div class="bg-background">
  <div class="bg-muted">
    <div class="bg-primary text-primary-foreground"></div>
  </div>
</div>

Borders and shadows

<!-- Borders -->
<div class="border border-border rounded-lg">
  <!-- Shadows -->
  <div class="shadow-sm">
    <!-- Small shadow -->
    <div class="shadow-md">
      <!-- Medium shadow -->
      <div class="shadow-lg"><!-- Large shadow --></div>
    </div>
  </div>
</div>

Responsive design

<!-- Mobile-first approach -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
  <!-- 1 column on mobile, 2 on tablet, 3 on desktop -->
</div>

<!-- Responsive padding -->
<div class="p-4 md:p-8 lg:p-12"></div>

Custom CSS

Adding custom utilities

Add custom utilities to app/assets/css/tailwind.css:

app/assets/css/tailwind.css
@import 'tailwindcss';

@layer utilities {
  .glass-effect {
    @apply bg-background/80 backdrop-blur-lg;
  }

  .scrollbar-hide {
    -ms-overflow-style: none;
    scrollbar-width: none;
  }
  .scrollbar-hide::-webkit-scrollbar {
    display: none;
  }
}

Then use them in your components:

<template>
  <div class="glass-effect">Glassmorphism effect</div>
</template>

Custom base styles

app/assets/css/tailwind.css
@layer base {
  * {
    @apply border-border;
  }

  body {
    @apply bg-background text-foreground;
  }
}

Pre-defined custom classes

The boilerplate includes some helpful custom classes:

base-container

A responsive container with consistent padding:

<template>
  <div class="base-container">
    <!-- Content with responsive padding and max-width -->
  </div>
</template>

Definition:

.base-container {
  @apply container mx-auto px-4 sm:px-6 lg:px-8;
}

Typography plugin

The boilerplate includes @tailwindcss/typography for styling markdown content:

<template>
  <article class="prose dark:prose-invert max-w-none">
    <ContentRenderer :value="post" />
  </article>
</template>

The prose class provides beautiful typography styles for:

  • Headings
  • Paragraphs
  • Lists
  • Blockquotes
  • Code blocks
  • Tables

Customizing prose styles

<template>
  <!-- Adjust max width -->
  <article class="prose prose-lg max-w-4xl">

  <!-- Modify specific elements -->
  <article class="prose prose-headings:font-semibold prose-a:text-primary">
</template>

Best practices

Use semantic color names

<!-- Good: Semantic naming -->
<div class="bg-primary text-primary-foreground">
  <!-- Avoid: Direct color values -->
  <div class="bg-blue-500 text-white"></div>
</div>

Utilize dark mode properly

<!-- Good: Specify both modes -->
<div class="bg-white dark:bg-black">
  <!-- Avoid: Only light mode -->
  <div class="bg-white"></div>
</div>

Keep utilities in template

<!-- Good: Utilities in template -->
<template>
  <div class="flex items-center gap-4 p-4">
</template>

<!-- Avoid: Custom CSS for simple layouts -->
<style>
.my-container {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem;
}
</style>

Use @apply sparingly

Only use @apply for complex, reusable patterns:

/* Good: Complex reusable component */
.button-primary {
  @apply px-4 py-2 bg-primary text-primary-foreground rounded-md
         hover:bg-primary/90 transition-colors;
}

/* Avoid: Simple utilities */
.text-center-class {
  @apply text-center;
}

Animations

Tailwind provides built-in animations. The boilerplate also uses tw-animate-css for additional animations:

<template>
  <!-- Fade in -->
  <div class="animate-in fade-in duration-500">

  <!-- Slide in -->
  <div class="animate-in slide-in-from-bottom-4 duration-300">

  <!-- Spin (loading indicator) -->
  <div class="animate-spin">
</template>

Debugging

View applied classes

Use browser DevTools to inspect elements and see which Tailwind classes are applied.

Tailwind IntelliSense

Install the Tailwind CSS IntelliSense extension for VS Code to get:

  • Autocomplete for class names
  • Linting for invalid classes
  • Hover previews of CSS values
  • Color decorators

Reference

For the complete list of Tailwind utilities and features, check the official Tailwind CSS documentation.