Skip to main content

Tailwind Configuration

The Tailwind CSS configuration extends the default theme with custom colors, animations, and font families tailored for the portfolio website.

Overview

Located in tailwind.config.mjs, this configuration file customizes Tailwind CSS with brand colors, smooth animations, and optimized settings.

Configuration Object

/** @type {import('tailwindcss').Config} */
export default {
    content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
    darkMode: 'class',
    theme: {
        extend: {
            // Custom extensions...
        },
    },
    plugins: [],
};

Content Sources

content
array
Glob patterns that define where Tailwind should look for class names
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}']
This pattern scans all files in the src directory with the following extensions:
  • .astro - Astro components
  • .html - HTML files
  • .js, .jsx - JavaScript files
  • .md, .mdx - Markdown files
  • .svelte - Svelte components
  • .ts, .tsx - TypeScript files
  • .vue - Vue components

Dark Mode

darkMode
string
default:"class"
Dark mode strategy using the class approach
darkMode: 'class'
Dark mode is toggled by adding the dark class to the HTML element. This is controlled by the ThemeToggle component (src/components/ThemeToggle.astro).

Theme Extensions

Font Family

Custom font stack with Inter as the primary sans-serif font:
fontFamily: {
    sans: ['Inter', 'system-ui', 'sans-serif'],
}
theme.extend.fontFamily.sans
array
Custom sans-serif font stack
  • Inter: Modern, professional typeface
  • system-ui: System default font fallback
  • sans-serif: Generic sans-serif fallback
Usage:
<p class="font-sans">Text using Inter font</p>

Custom Colors

Primary Color Scale

A comprehensive blue color palette for primary branding:
primary: {
    50: '#eff6ff',
    100: '#dbeafe',
    200: '#bfdbfe',
    300: '#93c5fd',
    400: '#60a5fa',
    500: '#3b82f6',
    600: '#2563eb',
    700: '#1d4ed8',
    800: '#1e40af',
    900: '#1e3a8a',
    950: '#172554',
}

Lighter Shades

  • primary-50 to primary-400: Light blue variants for backgrounds and hover states

Core Brand

  • primary-500: Main brand color (#3b82f6)
  • primary-600: Slightly darker for emphasis

Darker Shades

  • primary-700 to primary-950: Deep blues for text and dark mode
Usage Examples:
<!-- Background -->
<div class="bg-primary-500">Primary background</div>

<!-- Text -->
<h1 class="text-primary-700 dark:text-primary-300">Heading</h1>

<!-- Border -->
<button class="border-2 border-primary-600">Button</button>

<!-- Hover state -->
<a class="hover:bg-primary-100">Link</a>

Accent Color Scale

Cyan accent colors for highlights and interactive elements:
accent: {
    400: '#22d3ee',
    500: '#06b6d4',
    600: '#0891b2',
}
theme.extend.colors.accent
object
Cyan color variants for accents and CTAs
  • accent-400: Light cyan (#22d3ee)
  • accent-500: Core accent (#06b6d4)
  • accent-600: Dark cyan (#0891b2)
Usage Examples:
<!-- Accent highlight -->
<span class="text-accent-500">Featured text</span>

<!-- Gradient -->
<div class="bg-gradient-to-r from-primary-500 to-accent-500">
  Gradient background
</div>

Custom Animations

The configuration includes several custom animations for smooth, engaging interactions:
animation: {
    'float': 'float 8s ease-in-out infinite',
    'float-delayed': 'float 8s ease-in-out 2s infinite',
    'pulse-slow': 'pulse 4s cubic-bezier(0.4, 0, 0.6, 1) infinite',
    'gradient': 'gradient 8s ease infinite',
    'border-spin': 'border-spin 5s linear infinite',
}
Duration: 8 seconds
Timing: ease-in-out
Repeat: infinite
Creates a gentle vertical floating effect, moving the element up and down by 20px.
<div class="animate-float">Floating element</div>
Duration: 8 seconds
Timing: ease-in-out
Delay: 2 seconds
Repeat: infinite
Same as animate-float but starts with a 2-second delay, useful for staggered animations.
<div class="animate-float-delayed">Delayed float</div>
Duration: 4 seconds
Timing: cubic-bezier(0.4, 0, 0.6, 1)
Repeat: infinite
A slower, smoother pulse animation for subtle emphasis.
<div class="animate-pulse-slow">Pulsing badge</div>
Duration: 8 seconds
Timing: ease
Repeat: infinite
Animates the background position for smooth gradient transitions. Requires a gradient background.
<div class="bg-gradient-to-r from-primary-500 to-accent-500 bg-[length:200%_200%] animate-gradient">
  Animated gradient
</div>
Duration: 5 seconds
Timing: linear
Repeat: infinite
Rotates an element 360 degrees continuously. Useful for loading spinners or decorative borders.
<div class="animate-border-spin">Spinning border</div>

Keyframes

The animations are defined using custom keyframes:
keyframes: {
    float: {
        '0%, 100%': { transform: 'translateY(0px)' },
        '50%': { transform: 'translateY(-20px)' },
    },
    gradient: {
        '0%, 100%': { backgroundPosition: '0% 50%' },
        '50%': { backgroundPosition: '100% 50%' },
    },
    'border-spin': {
        '0%': { transform: 'rotate(0deg)' },
        '100%': { transform: 'rotate(360deg)' },
    },
}
float: {
    '0%, 100%': { transform: 'translateY(0px)' },
    '50%': { transform: 'translateY(-20px)' },
}
// Moves element up 20px at midpoint, returns to origin

Plugins

plugins: []
Currently, no additional Tailwind plugins are used. The configuration relies on Tailwind’s core utilities and custom extensions.

Usage Examples

Combining Custom Utilities

<!-- Card with custom colors and animation -->
<div class="bg-primary-50 dark:bg-primary-950 border-2 border-primary-200 dark:border-primary-800 animate-float">
  <h3 class="font-sans text-primary-900 dark:text-primary-100">
    Floating Card
  </h3>
  <p class="text-accent-600 dark:text-accent-400">
    With accent text
  </p>
</div>

<!-- Gradient button with hover effect -->
<button class="bg-gradient-to-r from-primary-600 to-accent-600 hover:from-primary-700 hover:to-accent-700 text-white font-sans px-6 py-3 rounded-lg transition-all duration-300">
  Click Me
</button>

<!-- Animated gradient background -->
<section class="bg-gradient-to-br from-primary-500 via-accent-500 to-primary-700 bg-[length:200%_200%] animate-gradient">
  <h1 class="text-white font-sans">Hero Section</h1>
</section>

Dark Mode Patterns

<!-- Responsive to dark mode -->
<div class="bg-white dark:bg-primary-900 text-primary-900 dark:text-white">
  Content that adapts to theme
</div>

<!-- Interactive with dark mode -->
<a class="text-primary-600 hover:text-accent-500 dark:text-primary-400 dark:hover:text-accent-400">
  Themed link
</a>

Integration with Astro

The Tailwind configuration is integrated with Astro via the @astrojs/tailwind integration:
// astro.config.mjs
import tailwind from '@astrojs/tailwind';

export default defineConfig({
  integrations: [tailwind({ applyBaseStyles: false })],
  // ...
});
Base Styles Disabled: The configuration uses applyBaseStyles: false, meaning Tailwind’s base reset styles are not applied. This gives more control over default styling.

Best Practices

Semantic Color Usage
  • Use primary-* for brand elements and main UI components
  • Use accent-* for highlights, CTAs, and interactive elements
  • Maintain consistent color scales across light and dark modes
Performance Optimization
  • The content glob pattern ensures only used classes are included in the final CSS
  • Custom animations use hardware-accelerated properties (transform, opacity)
  • Dark mode uses class strategy for instant theme switching
Animation Accessibility Consider adding prefers-reduced-motion media queries for users who prefer reduced motion:
<div class="motion-safe:animate-float">Only animates if motion is safe</div>
  • tailwind.config.mjs: Configuration file (tailwind.config.mjs:1)
  • astro.config.mjs: Astro integration (astro.config.mjs:5)
  • src/components/ThemeToggle.astro: Dark mode toggle (src/components/ThemeToggle.astro:1)

Build docs developers (and LLMs) love