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:
| Prefix | Min Width | Description |
|---|
sm: | 640px | Small devices |
md: | 768px | Medium devices |
lg: | 1024px | Large devices |
xl: | 1280px | Extra large |
2xl: | 1536px | 2X 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>
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
}
}