Skip to main content

Overview

The project uses Tailwind CSS for utility-first styling with custom theme extensions for brand colors and design system.

Installation

Tailwind is integrated via the official Astro integration:
npm install @astrojs/tailwind tailwindcss

Astro Integration

Enable Tailwind in astro.config.mjs:
import tailwind from '@astrojs/tailwind';

export default defineConfig({
  integrations: [
    tailwind(),
    // ... other integrations
  ],
});

Tailwind Configuration

Custom configuration in tailwind.config.mjs:
/** @type {import('tailwindcss').Config} */
export default {
  content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
  theme: {
    extend: {
      colors: {
        primary: '#22c55e',
      },
    },
  },
  plugins: [],
}

Content Configuration

File Scanning

Tailwind scans these patterns for class usage:
content: [
  './src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'
]
Includes:
  • Astro components
  • HTML templates
  • JavaScript/TypeScript files
  • MDX content
  • Framework components (Vue, Svelte, etc.)
Classes not found in scanned files will be purged from production builds.

Theme Customization

Brand Colors

Primary brand color defined as primary:
colors: {
  primary: '#22c55e', // Green
}
Usage:
<button class="bg-primary text-white hover:bg-primary/90">
  Click me
</button>

Additional Colors

Add more brand colors:
colors: {
  primary: '#22c55e',
  secondary: '#3b82f6',
  accent: '#f59e0b',
  dark: '#1f2937',
  light: '#f3f4f6',
}

Typography

Extend font families:
theme: {
  extend: {
    fontFamily: {
      sans: ['Inter', 'system-ui', 'sans-serif'],
      heading: ['Outfit', 'sans-serif'],
    },
  },
}

Spacing

Custom spacing values:
theme: {
  extend: {
    spacing: {
      '128': '32rem',
      '144': '36rem',
    },
  },
}

Using Tailwind

In Astro Components

---
// Component logic
---

<section class="bg-gray-50 py-16">
  <div class="container mx-auto px-4">
    <h2 class="text-4xl font-bold text-gray-900 mb-8">
      Heading
    </h2>
    <p class="text-lg text-gray-600">
      Content
    </p>
  </div>
</section>

With Custom CSS

Combine with custom styles:
---
// Component
---

<div class="card">
  <h3 class="text-2xl font-bold">Title</h3>
</div>

<style>
  .card {
    @apply bg-white rounded-lg shadow-lg p-6;
  }
</style>

Responsive Design

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
  <!-- Responsive grid -->
</div>
Breakpoints:
PrefixMin WidthDescription
sm:640pxSmall devices
md:768pxMedium devices
lg:1024pxLarge devices
xl:1280pxExtra large
2xl:1536px2X large

Dark Mode

Enable dark mode (if needed):
// tailwind.config.mjs
export default {
  darkMode: 'class',
  // ... rest of config
}
Usage:
<div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-white">
  Content
</div>

Plugins

Typography Plugin

For rich text formatting:
npm install @tailwindcss/typography
// tailwind.config.mjs
import typography from '@tailwindcss/typography';

export default {
  plugins: [typography],
}
Usage:
<article class="prose lg:prose-xl">
  <Content />
</article>

Forms Plugin

Better form styling:
npm install @tailwindcss/forms
import forms from '@tailwindcss/forms';

export default {
  plugins: [forms],
}

Container Queries

Responsive components:
npm install @tailwindcss/container-queries
import containerQueries from '@tailwindcss/container-queries';

export default {
  plugins: [containerQueries],
}

Optimization

Production Builds

Tailwind automatically:
  • Purges unused CSS
  • Minifies output
  • Optimizes for performance

JIT Mode

Just-In-Time mode is enabled by default:
  • Instant build times
  • All variants available
  • Arbitrary values supported
<div class="w-[347px] top-[117px]">
  <!-- Arbitrary values -->
</div>

Custom Directives

@apply

.btn {
  @apply px-4 py-2 bg-primary text-white rounded hover:bg-primary/90;
}

@layer

@layer components {
  .card {
    @apply bg-white rounded-lg shadow p-6;
  }
}

@variants

@variants hover, focus {
  .custom-utility {
    /* styles */
  }
}

Global Styles

Base styles in src/styles/global.css:
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  body {
    @apply bg-white text-gray-900;
  }
  
  h1 {
    @apply text-4xl font-bold;
  }
}
Import in layout:
---
import '../styles/global.css';
---

Best Practices

Component Classes

Extract repeated patterns:
---
const buttonClass = "px-6 py-3 bg-primary text-white rounded-lg hover:bg-primary/90 transition";
---

<button class={buttonClass}>Button 1</button>
<button class={buttonClass}>Button 2</button>

Conditional Classes

---
const variant = 'primary';
const variantClasses = {
  primary: 'bg-primary text-white',
  secondary: 'bg-gray-500 text-white',
};
---

<button class={`px-4 py-2 ${variantClasses[variant]}`}>
  Button
</button>

Avoiding Purge Issues

Don’t construct class names dynamically:
<!-- ❌ Bad: Will be purged -->
<div class={`text-${color}-500`}></div>

<!-- ✅ Good: Complete class names -->
<div class={color === 'red' ? 'text-red-500' : 'text-blue-500'}></div>

VS Code Integration

Install Tailwind CSS IntelliSense:
{
  "tailwindCSS.includeLanguages": {
    "astro": "html"
  },
  "editor.quickSuggestions": {
    "strings": true
  }
}

Build docs developers (and LLMs) love