Complete Tailwind CSS Tutorial

Master Tailwind CSS with our comprehensive tutorial.

Getting Started with Tailwind CSS

Set up and start using Tailwind CSS in your projects

What is Tailwind CSS?

Tailwind CSS is a utility-first CSS framework that provides low-level utility classes to build custom designs directly in your HTML.

Installation Methods

Method 1: Using CDN (Quick Start)
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
    <h1 class="text-3xl font-bold underline">
        Hello Tailwind!
    </h1>
</body>
</html>

Note: CDN is for development only. Not recommended for production.

Installation with npm/yarn

Method 2: Using Package Manager (Recommended)
# Create a new project directory
mkdir my-project
cd my-project

# Initialize npm
npm init -y

# Install Tailwind CSS
npm install -D tailwindcss

# Create tailwind config file
npx tailwindcss init

Configure Tailwind

tailwind.config.js
/** @type  {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{html,js}",
    "./public/**/*.html",
    "./index.html"
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Add Tailwind Directives

src/input.css
@tailwind base;
@tailwind components;
@tailwind utilities;

Build Process

Compile CSS
# Build CSS file
npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch

# Or add to package.json scripts
{
  "scripts": {
    "build": "tailwindcss -i ./src/input.css -o ./dist/output.css",
    "watch": "tailwindcss -i ./src/input.css -o ./dist/output.css --watch"
  }
}
# Run the build
npm run build

# Or watch for changes
npm run watch

Use in HTML

index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="./dist/output.css" rel="stylesheet">
</head>
<body>
    <div class="container mx-auto px-4">
        <h1 class="text-4xl font-bold text-blue-600">
            Welcome to Tailwind CSS
        </h1>
        <p class="text-gray-700 mt-4">
            Start building amazing interfaces!
        </p>
        <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded mt-4">
            Get Started
        </button>
    </div>
</body>
</html>

Framework Integration

Vite + React
# Create Vite project
npm create vite@latest my-app -- --template react
cd my-app

# Install Tailwind
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
// tailwind.config.js
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
/* src/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

First Example

Simple Card Component
<div class="max-w-sm rounded overflow-hidden shadow-lg">
    <img class="w-full" src="image.jpg" alt="Card image">
    <div class="px-6 py-4">
        <div class="font-bold text-xl mb-2">Card Title</div>
        <p class="text-gray-700 text-base">
            This is a simple card built with Tailwind CSS utility classes.
        </p>
    </div>
    <div class="px-6 pt-4 pb-2">
        <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">
            #tailwind
        </span>
        <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">
            #css
        </span>
    </div>
</div>

Editor Setup

VS Code Extensions
// Recommended extensions:
// 1. Tailwind CSS IntelliSense - Autocomplete
// 2. PostCSS Language Support - Syntax highlighting
// 3. Headwind - Class sorting

// settings.json
{
  "editor.quickSuggestions": {
    "strings": true
  },
  "tailwindCSS.emmetCompletions": true,
  "files.associations": {
    "*.css": "tailwindcss"
  }
}
Practice Tasks
  • Install Tailwind CSS using npm in a new project.
  • Create an HTML file and style a button with Tailwind utilities.
  • Build a simple card component using utility classes.
  • Set up the Tailwind CSS IntelliSense extension in VS Code.

Key Takeaways

  • Tailwind CSS is a utility-first framework with pre-defined classes.
  • Use CDN for quick prototyping, npm/yarn for production projects.
  • Configure content paths in tailwind.config.js for purging unused CSS.
  • Use @tailwind directives to inject base, components, and utilities.
  • Build process compiles your CSS and removes unused classes.

What's Next?

Next Topic: Learn about Tailwind CSS philosophy and features in the Introduction section.

Introduction to Tailwind CSS

Understanding the utility-first philosophy and core concepts

What is Tailwind CSS?

Tailwind CSS is a utility-first CSS framework that provides low-level utility classes to build custom designs without writing custom CSS.

Why Tailwind CSS?

Traditional CSS vs Tailwind
<!-- Traditional CSS -->
<style>
.alert {
    padding: 1rem;
    margin-bottom: 1rem;
    border: 1px solid transparent;
    border-radius: 0.25rem;
}
.alert-success {
    color: #155724;
    background-color: #d4edda;
    border-color: #c3e6cb;
}
</style>
<div class="alert alert-success">
    Success message
</div>

<!-- Tailwind CSS -->
<div class="p-4 mb-4 text-green-800 bg-green-100 border border-green-200 rounded">
    Success message
</div>

Key Features

Core Benefits
<!-- 1. No naming conventions needed -->
<div class="flex items-center justify-between p-4">
    <!-- No need to think of class names like .nav-header-container -->
</div>

<!-- 2. Responsive design built-in -->
<div class="w-full md:w-1/2 lg:w-1/3">
    <!-- Mobile: full width, Tablet: half, Desktop: one-third -->
</div>

<!-- 3. State variants -->
<button class="bg-blue-500 hover:bg-blue-700 focus:ring-2 active:bg-blue-900">
    Click me
</button>

<!-- 4. Dark mode support -->
<div class="bg-white dark:bg-gray-800 text-black dark:text-white">
    Content adapts to theme
</div>

<!-- 5. Customizable design system -->
<div class="text-brand-primary bg-brand-secondary">
    <!-- Use your own color palette -->
</div>

Utility Classes Overview

Common Utility Categories
<!-- Layout -->
<div class="container mx-auto">...</div>
<div class="flex flex-col items-center">...</div>
<div class="grid grid-cols-3 gap-4">...</div>

<!-- Spacing -->
<div class="p-4 m-2">Padding 1rem, Margin 0.5rem</div>
<div class="px-6 py-3">Horizontal padding 1.5rem, Vertical 0.75rem</div>

<!-- Typography -->
<h1 class="text-4xl font-bold text-gray-900">Title</h1>
<p class="text-base text-gray-600 leading-relaxed">Paragraph</p>

<!-- Colors -->
<div class="bg-blue-500 text-white">Blue background, white text</div>
<div class="border-2 border-red-500">Red border</div>

<!-- Sizing -->
<div class="w-64 h-32">Width 16rem, Height 8rem</div>
<div class="w-full h-screen">Full width and viewport height</div>

<!-- Effects -->
<div class="shadow-lg rounded-lg">Large shadow, large border radius</div>
<div class="opacity-50 blur-sm">Semi-transparent with blur</div>

Responsive Design

Mobile-First Breakpoints
<!-- Breakpoints: sm(640px), md(768px), lg(1024px), xl(1280px), 2xl(1536px) -->

<div class="text-sm sm:text-base md:text-lg lg:text-xl xl:text-2xl">
    Text size increases with screen size
</div>

<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
    <div>Item 1</div>
    <div>Item 2</div>
    <div>Item 3</div>
    <div>Item 4</div>
</div>

<!-- Mobile: 1 column, Tablet: 2 columns, Desktop: 3, Large: 4 -->

State Variants

Hover, Focus, and More
<!-- Hover states -->
<button class="bg-blue-500 hover:bg-blue-700 text-white">
    Hover to change color
</button>

<!-- Focus states -->
<input class="border-2 border-gray-300 focus:border-blue-500 focus:ring-2" type="text">

<!-- Active states -->
<button class="bg-green-500 active:bg-green-800">
    Click and hold
</button>

<!-- Disabled states -->
<button class="bg-blue-500 disabled:bg-gray-300 disabled:cursor-not-allowed" disabled>
    Disabled
</button>

<!-- Group hover -->
<div class="group hover:bg-gray-100">
    <p class="text-gray-900 group-hover:text-blue-600">
        Hover parent to change this
    </p>
</div>

<!-- First/last child -->
<ul>
    <li class="first:pt-0 last:pb-0 py-2">Item 1</li>
    <li class="first:pt-0 last:pb-0 py-2">Item 2</li>
    <li class="first:pt-0 last:pb-0 py-2">Item 3</li>
</ul>

Customization

Extend the Framework
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        brand: {
          light: '#85d7ff',
          DEFAULT: '#1fb6ff',
          dark: '#009eeb',
        }
      },
      spacing: {
        '128': '32rem',
        '144': '36rem',
      },
      fontFamily: {
        sans: ['Inter', 'sans-serif'],
      },
      borderRadius: {
        '4xl': '2rem',
      }
    }
  },
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/typography'),
  ],
}
<!-- Use custom values -->
<div class="bg-brand text-white p-128 rounded-4xl font-sans">
    Custom styling
</div>

Advantages

Benefits of Tailwind
✅ No CSS file bloat - unused styles are purged
✅ Consistent design system - predefined spacing, colors
✅ Fast development - no context switching to CSS files
✅ Easy maintenance - changes in HTML only
✅ Responsive by default - mobile-first approach
✅ Highly customizable - extend or override anything
✅ Great tooling - VS Code extension, Play CDN
✅ Component-friendly - works with React, Vue, etc.

Potential Concerns

Common Criticisms
<!-- Concern: Long class strings -->
<button class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
    Button
</button>

<!-- Solution 1: Extract components -->
<button class="btn-primary">Button</button>

<!-- Solution 2: Use component frameworks -->
<!-- Vue, React components encapsulate complexity -->

<!-- Solution 3: Use @apply directive -->
<style>
.btn-primary {
    @apply inline-flex items-center px-4 py-2 bg-indigo-600 text-white rounded-md;
    @apply hover:bg-indigo-700 focus:ring-2 focus:ring-indigo-500;
}
</style>

When to Use Tailwind

Use Cases
✅ Perfect for:
- New projects with custom designs
- Rapid prototyping
- Component-based frameworks (React, Vue, Angular)
- Projects requiring consistent design system
- Teams wanting to avoid CSS architecture debates

❌ Maybe not ideal for:
- Simple static sites (might be overkill)
- Projects with strict CSS methodologies (BEM, OOCSS)
- Teams unfamiliar with utility-first approach
- Legacy codebases with existing CSS
Practice Tasks
  • Create a button with hover and focus states using Tailwind.
  • Build a responsive card that changes layout on different screen sizes.
  • Style a form with proper spacing and colors.
  • Experiment with different utility combinations.

Key Takeaways

  • Tailwind is a utility-first framework with pre-defined classes.
  • No need to write custom CSS or invent class names.
  • Built-in responsive design with mobile-first breakpoints.
  • State variants (hover, focus, active) are easy to apply.
  • Highly customizable through configuration file.
  • Automatic CSS purging keeps bundle size small.

What's Next?

Next Topic: Explore the History of Tailwind CSS and its evolution.

History of Tailwind CSS

From inception to modern utility-first framework

The Beginning

Tailwind CSS was created by Adam Wathan, Jonathan Reinink, David Hemphill, and Steve Schoger. Released in November 2017, it introduced a new approach to CSS with utility-first methodology.

Timeline of Major Releases

Version History
📅 November 2017 - Tailwind CSS v0.1.0
- Initial release
- Basic utility classes
- Configuration system

📅 May 2019 - Tailwind CSS v1.0
- Production-ready release
- PurgeCSS integration
- New color palette
- Improved documentation
- Plugin system

📅 November 2020 - Tailwind CSS v2.0
- New color palette (extended)
- Dark mode support
- Extra wide 2xl breakpoint
- Form plugin improvements
- Additional utility classes
- @apply  improvements

📅 December 2021 - Tailwind CSS v3.0
- Just-in-Time (JIT) engine by default
- Every variant enabled by default
- Colored box shadows
- Multi-column layout utilities
- Fancy underline utilities
- Native form control styling
- Print modifier
- Portrait/landscape modifiers
- Smaller file sizes

📅 2022-2024 - Continuous improvements
- v3.1: Container queries, arbitrary variants
- v3.2: Dynamic breakpoints, multiple config files
- v3.3: ESM/TypeScript support, simplified RTL
- v3.4: New color palette, dynamic viewport units

Tailwind CSS v1.0 (2019)

First Stable Release
// tailwind.config.js (v1.0)
module.exports = {
  theme: {
    colors: {
      // New default color palette
      gray: {
        100: '#f7fafc',
        200: '#edf2f7',
        // ... more shades
      },
      red: {
        100: '#fff5f5',
        500: '#f56565',
        900: '#742a2a',
      }
    },
    spacing: {
      // Consistent spacing scale
      '1': '0.25rem',
      '2': '0.5rem',
      '4': '1rem',
      '8': '2rem',
    }
  },
  variants: {
    // Control which variants are generated
    backgroundColor: ['responsive', 'hover', 'focus'],
  },
  plugins: [
    // Plugin system introduced
  ],
}
<!-- v1.0 usage -->
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
    Button
</button>

Tailwind CSS v2.0 (2020)

Dark Mode and Extended Colors
// tailwind.config.js (v2.0)
module.exports = {
  darkMode: 'media', // or 'class'
  theme: {
    extend: {
      colors: {
        // Extended color palette with more shades
        gray: {
          50: '#fafafa',
          100: '#f5f5f5',
          // ... 900
        }
      }
    }
  },
  variants: {
    extend: {
      backgroundColor: ['active', 'disabled'],
    }
  }
}
<!-- Dark mode support -->
<div class="bg-white dark:bg-gray-800">
    <p class="text-gray-900 dark:text-white">
        Content adapts to dark mode
    </p>
</div>

<!-- New 2xl breakpoint -->
<div class="text-base xl:text-lg 2xl:text-xl">
    Responsive on extra large screens
</div>

Tailwind CSS v3.0 (2021)

JIT Engine and Performance
// tailwind.config.js (v3.0)
module.exports = {
  content: ['./src/**/*.{html,js}'], // Replaces 'purge'
  theme: {
    extend: {
      // Arbitrary values supported everywhere
    }
  },
  // All variants enabled by default - no need to configure
}
<!-- JIT Engine: Generate styles on-demand -->

<!-- Arbitrary values -->
<div class="top-[117px] lg:top-[344px]">Custom spacing</div>
<div class="bg-[#1da1f2]">Twitter blue</div>
<div class="grid-cols-[200px_minmax(900px,_1fr)_100px]">Complex grid</div>

<!-- Colored shadows -->
<div class="shadow-lg shadow-blue-500/50">Blue shadow</div>

<!-- Fancy underlines -->
<a class="underline decoration-pink-500 decoration-wavy decoration-2">
    Wavy pink underline
</a>

<!-- Multi-column layout -->
<div class="columns-3 gap-8">
    Multi-column text
</div>

<!-- Print styles -->
<div class="hidden print:block">
    Only visible when printing
</div>

Key Innovations

Groundbreaking Features
<!-- 1. Utility-First Philosophy -->
<!-- Before: Write custom CSS for every component -->
<!-- After: Compose from utilities -->

<!-- 2. Responsive Design -->
<div class="w-full md:w-1/2 lg:w-1/3">
    Responsive without media queries in CSS
</div>

<!-- 3. State Variants -->
<button class="bg-blue-500 hover:bg-blue-700 focus:ring active:bg-blue-900">
    All states in one line
</button>

<!-- 4. Dark Mode -->
<div class="bg-white dark:bg-black">
    Automatic dark mode support
</div>

<!-- 5. JIT Engine (v3.0+) -->
<!-- Generate only the styles you use, instantly -->
<div class="mt-[137px] bg-[#bada55]">
    Any value, generated on-demand
</div>

<!-- 6. Plugin System -->
<!-- Extend with official and community plugins -->

Ecosystem Growth

Official Tools and Libraries
🎨 Tailwind UI (2020)
- Premium component library
- Production-ready components
- React and Vue versions

🎮 Tailwind Play (2021)
- Online playground
- Share designs instantly
- No setup required

📝 Tailwind CSS Typography (2019)
- Beautiful typographic defaults
- Prose class for content

📋 Tailwind CSS Forms (2020)
- Better form defaults
- Consistent styling across browsers

🔌 Headless UI (2020)
- Unstyled, accessible components
- React and Vue versions
- Perfect for custom designs

⚡ Tailwind CSS IntelliSense (2019)
- VS Code extension
- Autocomplete and linting
- Class name suggestions

Adoption and Impact

Industry Recognition
📈 Growth Metrics:
- Over 10 million+ weekly npm downloads (2024)
- 75,000+ GitHub stars
- Used by Netflix, NASA, Laravel, and more
- Top CSS framework in State of CSS surveys

🏆 Awards:
- "Most Adopted Technology" - State of CSS 2021
- High satisfaction ratings year over year

👥 Community:
- Active Discord community
- Thousands of plugins and components
- Extensive third-party resources
- Regular conferences and meetups

Philosophy Evolution

Core Principles
🎯 Original Vision:
"Create websites without leaving your HTML"

💡 Key Insights:
1. Naming things is hard - use utilities instead
2. CSS bloat comes from writing new CSS - reuse utilities
3. Responsive design should be easy - built-in breakpoints
4. Customization matters - configuration over conventions
5. Performance is critical - automatic purging

🔄 Continuous Improvement:
- Listen to community feedback
- Prioritize developer experience
- Balance power with simplicity
- Maintain backward compatibility
- Regular updates and improvements

Looking Forward

Future Directions
🔮 Ongoing Development:
- Better TypeScript support
- Enhanced tooling and editor integration
- More plugins and ecosystem growth
- Container queries and modern CSS features
- Improved performance and smaller builds
- Better component extraction tools

🌟 Vision:
"Make building modern websites faster and more enjoyable
while maintaining flexibility and customization."
Practice Tasks
  • Compare code examples from v1.0 vs v3.0 to see evolution.
  • Try arbitrary values with the JIT engine.
  • Explore the Tailwind Play playground online.
  • Read the official changelog to understand version differences.

Key Takeaways

  • Tailwind CSS launched in 2017 with utility-first approach.
  • v1.0 (2019) brought production-ready features and plugins.
  • v2.0 (2020) added dark mode and extended color palette.
  • v3.0 (2021) introduced JIT engine for better performance.
  • Continuous evolution with new features and improvements.
  • Strong ecosystem with UI libraries, plugins, and tools.

What's Next?

Next Topic: Dive deep into the Utility-First philosophy.

Utility-First CSS Philosophy

Understanding the core approach of Tailwind CSS

What is Utility-First CSS?

Utility-first CSS is a design approach where you build designs by composing small, single-purpose utility classes rather than writing custom CSS for each component.

Traditional vs Utility-First

Comparison
<!-- Traditional Approach -->
<style>
.author-card {
    display: flex;
    align-items: center;
    padding: 1.5rem;
    background-color: white;
    border-radius: 0.5rem;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.author-card__avatar {
    width: 4rem;
    height: 4rem;
    border-radius: 9999px;
    margin-right: 1rem;
}

.author-card__name {
    font-size: 1.25rem;
    font-weight: 600;
    color: #1a202c;
}

.author-card__role {
    font-size: 0.875rem;
    color: #718096;
}
</style>

<div class="author-card">
    <img class="author-card__avatar" src="avatar.jpg" alt="Author">
    <div>
        <h3 class="author-card__name">John Doe</h3>
        <p class="author-card__role">Software Engineer</p>
    </div>
</div>
<!-- Utility-First Approach -->
<div class="flex items-center p-6 bg-white rounded-lg shadow-md">
    <img class="w-16 h-16 rounded-full mr-4" src="avatar.jpg" alt="Author">
    <div>
        <h3 class="text-xl font-semibold text-gray-900">John Doe</h3>
        <p class="text-sm text-gray-600">Software Engineer</p>
    </div>
</div>

Benefits of Utility-First

1. No Naming Convention Headaches
/* Traditional: Spend time naming things */
.card { }
.card--featured { }
.card__header { }
.card__header--large { }
.card__body { }
.card__footer { }

/* Questions arise: */
/* - Use BEM? OOCSS? SMACSS? */
/* - How to name variations? */
/* - What if requirements change? */
<!-- Utility-first: No naming needed -->
<div class="border rounded-lg shadow-md">
    <div class="p-4 border-b">Header</div>
    <div class="p-4">Body</div>
    <div class="p-4 bg-gray-50">Footer</div>
</div>

Benefits: CSS Doesn't Grow

2. Reuse Utilities Instead of Adding CSS
/* Traditional: CSS grows with every new feature */
.button-primary { }
.button-secondary { }
.button-large { }
.button-small { }
.alert-success { }
.alert-error { }
.card-blog { }
.card-product { }
/* ... hundreds more classes */

/* Result: 200KB+ of CSS */
<!-- Utility-first: Reuse the same utilities -->
<button class="px-4 py-2 bg-blue-500 text-white rounded">Primary</button>
<button class="px-4 py-2 bg-gray-500 text-white rounded">Secondary</button>
<button class="px-6 py-3 bg-blue-500 text-white rounded">Large</button>
<button class="px-2 py-1 bg-blue-500 text-white rounded">Small</button>

<!-- Same utilities, different combinations -->
<!-- Result: 10-20KB of CSS after purging -->

Benefits: Easier Changes

3. Make Changes Safely
/* Traditional: Changes affect everything */
.button {
    padding: 0.5rem 1rem;
    background: blue;
}

/* Change this and you might break: */
/* - Homepage button */
/* - Checkout button */
/* - Nav button */
/* - Modal button */
/* ... etc */

/* Fear of changing CSS! */
<!-- Utility-first: Local changes only -->
<!-- Before -->
<button class="px-4 py-2 bg-blue-500">Click me</button>

<!-- After: Change is isolated to this button only -->
<button class="px-6 py-3 bg-green-500">Click me</button>

<!-- Other buttons unaffected -->

Benefits: Mobile-First Responsive

4. Built-in Responsive Design
/* Traditional: Write media queries */
.sidebar {
    width: 100%;
}

@media(min-width: 768px) {
    .sidebar {
        width: 33.333%;
    }
}

@media(min-width: 1024px) {
    .sidebar {
        width: 25%;
    }
}
<!-- Utility-first: Responsive in HTML -->
<div class="w-full md:w-1/3 lg:w-1/4">
    Sidebar
</div>

<!-- Mobile: full width -->
<!-- Tablet: 1/3 width -->
<!-- Desktop: 1/4 width -->

Addressing Common Concerns

Concern 1: "HTML is Ugly"
<!-- Yes, classes can be long -->
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">
    Button
</button>

<!-- But you can extract components -->
<!-- 1. Template partials -->
{{ include('components/button', ['text' => 'Click me']) }}

<!-- 2. Component frameworks (React) -->
<Button variant="primary">Click me</Button>

<!-- 3. @apply  directive -->
<style>
.btn-primary {
    @apply bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded;
}
</style>

<button class="btn-primary">Button</button>

When to Extract Components

Concern 2: "When to Use @apply?"
<!-- Don't extract too early -->
<!-- ❌ Bad: Premature abstraction -->
<style>
.text-large { @apply text-lg; }
.mt-small { @apply mt-2; }
</style>
<!-- This defeats the purpose of utilities -->

<!-- ✅ Good: Extract when repeated many times -->
<!-- If you have 50+ buttons, extract -->
<style>
.btn {
    @apply px-4 py-2 rounded font-semibold;
}
.btn-primary {
    @apply bg-blue-500 text-white hover:bg-blue-700;
}
.btn-secondary {
    @apply bg-gray-300 text-gray-800 hover:bg-gray-400;
}
</style>

<!-- ✅ Best: Use component framework -->
<!-- React/Vue components are ideal for repetition -->

Utility-First in Practice

Building a Real Component
<!-- Product Card -->
<div class="max-w-sm rounded-lg overflow-hidden shadow-lg bg-white hover:shadow-2xl transition-shadow duration-300">
    <!-- Image -->
    <img class="w-full h-48 object-cover" src="product.jpg" alt="Product">

    <!-- Content -->
    <div class="p-6">
        <!-- Category Badge -->
        <span class="inline-block bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full font-semibold tracking-wide">
            Electronics
        </span>

        <!-- Title -->
        <h3 class="mt-2 text-xl font-bold text-gray-900">
            Wireless Headphones
        </h3>

        <!-- Description -->
        <p class="mt-3 text-gray-600 text-sm leading-relaxed">
            Premium noise-cancelling headphones with 30-hour battery life.
        </p>

        <!-- Price and Button -->
        <div class="mt-4 flex items-center justify-between">
            <span class="text-2xl font-bold text-gray-900">$299</span>
            <button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg transition-colors">
                Add to Cart
            </button>
        </div>
    </div>
</div>

Design Consistency

Utility-First Enforces Consistency
<!-- Traditional: Every developer uses different values -->
<style>
.header { padding: 20px; }
.content { padding: 18px; }
.footer { padding: 1.2rem; }
.sidebar { padding: 22px; }
</style>

<!-- Utility-first: Everyone uses the same scale -->
<div class="p-4">Header</div>    <!-- 1rem -->
<div class="p-4">Content</div>  <!-- 1rem -->
<div class="p-4">Footer</div>   <!-- 1rem -->
<div class="p-5">Sidebar</div>  <!-- 1.25rem -->

<!-- Predefined spacing scale: */
<!-- 0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24... -->
<!-- Result: Consistent design system -->

Mindset Shift

Thinking Utility-First
Traditional Approach:
1. Look at design
2. Think of component name (.card, .profile, .hero)
3. Write CSS for that component
4. Apply class to HTML
5. Repeat for every component

Utility-First Approach:
1. Look at design
2. Break down into visual properties
   - What's the layout? (flex, grid)
   - What's the spacing? (p-4, m-2)
   - What are the colors? (bg-blue-500, text-white)
   - What's the typography? (text-xl, font-bold)
3. Compose utilities in HTML
4. Done!

Key: Think in properties, not components
Practice Tasks
  • Rebuild a component from your project using only utilities.
  • Compare file sizes: traditional CSS vs utility-first approach.
  • Create 5 different button styles using the same utilities.
  • Build a card component without writing any custom CSS.

Key Takeaways

  • Utility-first means composing designs from small, single-purpose classes.
  • Eliminates the need for naming conventions and CSS architecture debates.
  • CSS doesn't grow because you reuse the same utilities.
  • Changes are localized and safe - no unexpected side effects.
  • Built-in responsive design with mobile-first breakpoints.
  • Enforces consistency through predefined design scales.
  • Extract components when you have significant repetition.

What's Next?

Next Topic: Learn about Responsive Design with Tailwind CSS breakpoints.

Responsive Design in Tailwind CSS

Build mobile-first, responsive interfaces with breakpoint prefixes

Mobile-First Philosophy

Tailwind uses a mobile-first approach where unprefixed utilities apply to all screen sizes, and prefixed utilities override them at larger breakpoints.

Breakpoint System

Default Breakpoints
// tailwind.config.js default breakpoints
module.exports = {
  theme: {
    screens: {
      'sm': '640px',   // @media(min-width: 640px)
      'md': '768px',   // @media(min-width: 768px)
      'lg': '1024px',  // @media(min-width: 1024px)
      'xl': '1280px',  // @media(min-width: 1280px)
      '2xl': '1536px', // @media(min-width: 1536px)
    }
  }
}
<!-- Mobile-first approach -->
<div class="text-sm sm:text-base md:text-lg lg:text-xl xl:text-2xl">
    Responsive text size
</div>

<!-- Breakdown:
     Mobile (< 640px):     text-sm
     Small (>= 640px):     text-base
     Medium (>= 768px):    text-lg
     Large (>= 1024px):    text-xl
     Extra Large (>= 1280px): text-2xl
-->

Responsive Layout

Grid Columns Example
<!-- Responsive grid -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
    <div class="bg-blue-500 p-4">Item 1</div>
    <div class="bg-blue-500 p-4">Item 2</div>
    <div class="bg-blue-500 p-4">Item 3</div>
    <div class="bg-blue-500 p-4">Item 4</div>
</div>

<!-- Behavior:
     Mobile:  1 column (stacked)
     Tablet:  2 columns
     Desktop: 3 columns
     Large:   4 columns
-->

Responsive Width

Container Width
<!-- Full width on mobile, constrained on larger screens -->
<div class="w-full md:w-3/4 lg:w-1/2 xl:w-1/3 mx-auto">
    Content container
</div>

<!-- Widths:
     Mobile:  100% width
     Medium:  75% width
     Large:   50% width
     XLarge:  33.33% width
-->

<!-- Sidebar layout -->
<div class="flex flex-col lg:flex-row">
    <aside class="w-full lg:w-64">
        Sidebar (full width on mobile, fixed on desktop)
    </aside>
    <main class="flex-1">
        Main content
    </main>
</div>

Responsive Display

Show/Hide Elements
<!-- Hide on mobile, show on desktop -->
<div class="hidden lg:block">
    Desktop navigation
</div>

<!-- Show on mobile, hide on desktop -->
<button class="block lg:hidden">
    Mobile menu button
</button>

<!-- Different displays per breakpoint -->
<div class="block md:inline-block lg:flex">
    Responsive display
</div>

<!-- Responsive navigation example -->
<nav class="flex items-center justify-between">
    <div class="text-xl font-bold">Logo</div>

    <!-- Desktop menu -->
    <ul class="hidden md:flex space-x-4">
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact</a></li>
    </ul>

    <!-- Mobile menu button -->
    <button class="md:hidden">
        ☰
    </button>
</nav>

Responsive Spacing

Padding and Margin
<!-- Increase padding on larger screens -->
<div class="p-4 md:p-6 lg:p-8 xl:p-12">
    More padding as screen grows
</div>

<!-- Responsive margins -->
<section class="my-8 md:my-12 lg:my-16">
    Vertical margins increase with screen size
</section>

<!-- Responsive gap in grid -->
<div class="grid grid-cols-2 gap-2 md:gap-4 lg:gap-6">
    <div>Item 1</div>
    <div>Item 2</div>
</div>

Responsive Typography

Text Size and Line Height
<!-- Responsive heading -->
<h1 class="text-2xl md:text-3xl lg:text-4xl xl:text-5xl font-bold">
    Responsive Heading
</h1>

<!-- Responsive paragraph -->
<p class="text-sm md:text-base lg:text-lg leading-normal md:leading-relaxed">
    Paragraph text that grows and has better line spacing on larger screens.
</p>

<!-- Hero section with responsive typography -->
<div class="text-center py-12 md:py-20">
    <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold mb-4">
        Welcome
    </h1>
    <p class="text-lg md:text-xl lg:text-2xl text-gray-600">
        Build amazing websites
    </p>
</div>

Custom Breakpoints

Customize Breakpoints
// tailwind.config.js
module.exports = {
  theme: {
    screens: {
      // Custom breakpoints
      'xs': '475px',
      'sm': '640px',
      'md': '768px',
      'lg': '1024px',
      'xl': '1280px',
      '2xl': '1400px',
      '3xl': '1600px',

      // Or replace entirely
      'tablet': '640px',
      'laptop': '1024px',
      'desktop': '1280px',
    },
    // Or extend existing
    extend: {
      screens: {
        '3xl': '1600px',
      },
    },
  },
}
<!-- Use custom breakpoints -->
<div class="text-base 3xl:text-xl">
    Extra large screen text
</div>

Max-Width Breakpoints

Max-Width Media Queries
// tailwind.config.js
module.exports = {
  theme: {
    screens: {
      // Max-width breakpoints
      'max-2xl': {'max': '1535px'},
      'max-xl': {'max': '1279px'},
      'max-lg': {'max': '1023px'},
      'max-md': {'max': '767px'},
      'max-sm': {'max': '639px'},
    },
  },
}
<!-- Apply styles only below breakpoint -->
<div class="text-xl max-md:text-base">
    Large text on desktop, smaller on mobile
</div>

<!-- Mobile-only styles -->
<div class="max-md:text-center max-md:p-2">
    Centered with small padding on mobile only
</div>

Range Breakpoints

Target Specific Ranges
// tailwind.config.js
module.exports = {
  theme: {
    screens: {
      'tablet-only': {'min': '640px', 'max': '1023px'},
    },
  },
}
<!-- Apply only on tablets -->
<div class="tablet-only:grid-cols-2">
    Two columns only on tablets
</div>

Responsive Card Example

Complete Responsive Component
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    <!-- Responsive grid -->
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6 lg:gap-8">
        <!-- Card -->
        <div class="bg-white rounded-lg shadow-md hover:shadow-xl transition-shadow">
            <img
                class="w-full h-48 sm:h-56 md:h-64 object-cover rounded-t-lg"
                src="image.jpg"
                alt="Card"
            >
            <div class="p-4 md:p-6">
                <h3 class="text-lg md:text-xl lg:text-2xl font-bold mb-2">
                    Card Title
                </h3>
                <p class="text-sm md:text-base text-gray-600 mb-4">
                    Card description that adapts to screen size.
                </p>
                <button class="w-full md:w-auto px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
                    Learn More
                </button>
            </div>
        </div>
    </div>
</div>

Responsive Container

Container Class
<!-- Container with responsive max-width -->
<div class="container mx-auto px-4">
    Content is centered with responsive padding
</div>

<!-- Container breakpoints:
     None:   width: 100%
     sm:     max-width: 640px
     md:     max-width: 768px
     lg:     max-width: 1024px
     xl:     max-width: 1280px
     2xl:    max-width: 1536px
-->

Testing Responsive Design

Browser DevTools
1. Open Chrome/Firefox DevTools (F12)
2. Click device toolbar icon (Ctrl+Shift+M)
3. Test different device sizes:
   - Mobile: 375px (iPhone)
   - Tablet: 768px (iPad)
   - Desktop: 1440px
4. Check each breakpoint
5. Test orientation (portrait/landscape)

Or use responsive design mode to see multiple sizes at once.
Practice Tasks
  • Create a navigation that's horizontal on desktop, vertical on mobile.
  • Build a responsive grid with 1, 2, 3, and 4 columns.
  • Make a hero section with responsive text sizes and spacing.
  • Test your design at all breakpoints using browser DevTools.

Key Takeaways

  • Tailwind uses mobile-first responsive design approach.
  • Five default breakpoints: sm, md, lg, xl, 2xl.
  • Prefix any utility with breakpoint to apply at that size.
  • Unprefixed utilities apply to all screen sizes.
  • Can customize breakpoints in tailwind.config.js.
  • Use container class for responsive max-width containers.

What's Next?

Next Topic: Learn about the Container utility and layout helpers.

Hover & Focus States in Tailwind CSS

Create interactive elements with state variants and pseudo-classes

Understanding State Variants

Tailwind provides state variants (like hover:, focus:, active:) that allow you to apply styles conditionally based on element state. These variants make it easy to create interactive and accessible user interfaces.

Hover States

Basic Hover Effects
<!-- Hover background color -->
<button class="bg-blue-500 hover:bg-blue-700 text-white px-6 py-2 rounded">
    Hover me
</button>

<!-- Hover text color -->
<a href="#" class="text-blue-600 hover:text-blue-800">
    Hover link
</a>

<!-- Hover border -->
<div class="border-2 border-gray-300 hover:border-blue-500 p-4">
    Hover to change border
</div>

<!-- Multiple hover effects -->
<button class="bg-white text-gray-700 border-2 border-gray-300
               hover:bg-blue-500 hover:text-white hover:border-blue-500
               px-6 py-2 rounded transition">
    Multi-effect hover
</button>
Hover Transforms and Effects
<!-- Hover scale -->
<button class="hover:scale-105 transform transition px-6 py-2 bg-blue-500 text-white rounded">
    Scale on hover
</button>

<!-- Hover shadow -->
<div class="bg-white p-6 rounded-lg shadow hover:shadow-xl transition">
    Card with hover shadow
</div>

<!-- Hover translate -->
<button class="hover:-translate-y-1 transform transition bg-green-500 text-white px-6 py-2 rounded">
    Lift on hover
</button>

<!-- Hover opacity -->
<img src="image.jpg" class="opacity-70 hover:opacity-100 transition">

Focus States

Focus Effects for Inputs
<!-- Focus border color -->
<input type="text"
       class="border-2 border-gray-300 focus:border-blue-500 focus:outline-none px-4 py-2 rounded">

<!-- Focus ring -->
<input type="text"
       class="border-2 border-gray-300 focus:ring-2 focus:ring-blue-500 focus:border-transparent px-4 py-2 rounded">

<!-- Focus background -->
<input type="text"
       class="bg-gray-100 focus:bg-white border-2 border-transparent focus:border-blue-500 px-4 py-2 rounded">

<!-- Textarea with focus -->
<textarea class="w-full border-2 border-gray-300 focus:border-purple-500 focus:ring-2 focus:ring-purple-200 rounded px-4 py-2">
</textarea>
Focus Visible (Keyboard Only)
<!-- Focus visible for accessibility -->
<button class="bg-blue-500 text-white px-6 py-2 rounded
               focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-300">
    Keyboard focus only
</button>

<!-- Link with focus visible -->
<a href="#" class="text-blue-600 focus:outline-none focus-visible:underline focus-visible:ring-2 focus-visible:ring-blue-300 rounded px-2">
    Accessible link
</a>

Active States

Active (Click) States
<!-- Active background -->
<button class="bg-blue-500 hover:bg-blue-600 active:bg-blue-800 text-white px-6 py-2 rounded">
    Click me
</button>

<!-- Active scale -->
<button class="bg-green-500 text-white px-6 py-2 rounded
               hover:scale-105 active:scale-95 transform transition">
    Press effect
</button>

<!-- Active shadow -->
<button class="bg-purple-500 text-white px-6 py-2 rounded shadow-lg active:shadow-inner">
    Shadow press
</button>

Group Hover

Parent-Child Hover Interaction
<!-- Group hover card -->
<div class="group border rounded-lg p-6 hover:bg-gray-50 cursor-pointer">
    <h3 class="text-gray-900 group-hover:text-blue-600 font-bold">
        Card Title
    </h3>
    <p class="text-gray-600 group-hover:text-gray-900">
        This text changes when you hover the card
    </p>
    <button class="mt-4 bg-gray-200 group-hover:bg-blue-500 group-hover:text-white px-4 py-2 rounded">
        Learn More
    </button>
</div>

<!-- Image overlay on group hover -->
<div class="group relative overflow-hidden rounded-lg">
    <img src="image.jpg" class="group-hover:scale-110 transition duration-300">
    <div class="absolute inset-0 bg-black opacity-0 group-hover:opacity-50 transition"></div>
    <div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition">
        <button class="bg-white text-gray-900 px-6 py-2 rounded">View</button>
    </div>
</div>

Peer States

Sibling Element Interaction
<!-- Peer checkbox example -->
<div class="flex items-center">
    <input type="checkbox" id="terms" class="peer sr-only">
    <label for="terms" class="peer-checked:bg-blue-500 peer-checked:text-white bg-gray-200 text-gray-700 px-4 py-2 rounded cursor-pointer">
        Accept Terms
    </label>
</div>

<!-- Peer focus example -->
<div class="relative">
    <input type="text" id="email" class="peer border-2 border-gray-300 px-4 py-2 rounded w-full" placeholder=" ">
    <label for="email" class="absolute left-4 -top-2.5 bg-white px-1 text-sm text-gray-600 peer-focus:text-blue-500 peer-focus:font-medium">
        Email
    </label>
</div>

<!-- Radio button with peer -->
<div class="space-y-2">
    <div class="flex items-center">
        <input type="radio" name="plan" id="basic" class="peer/basic sr-only">
        <label for="basic" class="peer-checked/basic:border-blue-500 peer-checked/basic:bg-blue-50 border-2 rounded-lg p-4 w-full cursor-pointer">
            Basic Plan - $10/mo
        </label>
    </div>
    <div class="flex items-center">
        <input type="radio" name="plan" id="pro" class="peer/pro sr-only">
        <label for="pro" class="peer-checked/pro:border-purple-500 peer-checked/pro:bg-purple-50 border-2 rounded-lg p-4 w-full cursor-pointer">
            Pro Plan - $25/mo
        </label>
    </div>
</div>

Disabled States

Disabled Element Styling
<!-- Disabled button -->
<button class="bg-blue-500 text-white px-6 py-2 rounded
               disabled:bg-gray-300 disabled:text-gray-500 disabled:cursor-not-allowed"
        disabled>
    Disabled Button
</button>

<!-- Disabled input -->
<input type="text"
       class="border-2 border-gray-300 px-4 py-2 rounded
              disabled:bg-gray-100 disabled:text-gray-400 disabled:cursor-not-allowed"
       disabled
       value="Disabled input">

<!-- Conditionally disabled -->
<button class="bg-green-500 hover:bg-green-600 text-white px-6 py-2 rounded
               disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-green-500">
    Submit
</button>

Practical Interactive Examples

Real-World Interactive Patterns
<!-- Interactive card -->
<div class="group bg-white rounded-lg shadow hover:shadow-2xl transition-all duration-300 overflow-hidden cursor-pointer">
    <div class="relative overflow-hidden">
        <img src="product.jpg" class="w-full h-48 object-cover group-hover:scale-110 transition-transform duration-300">
        <div class="absolute top-2 right-2 bg-red-500 text-white px-2 py-1 rounded text-sm">
            Sale
        </div>
    </div>
    <div class="p-6">
        <h3 class="text-xl font-bold mb-2 group-hover:text-blue-600 transition">
            Product Name
        </h3>
        <p class="text-gray-600 mb-4">$49.99</p>
        <button class="w-full bg-blue-500 text-white py-2 rounded group-hover:bg-blue-600 transition">
            Add to Cart
        </button>
    </div>
</div>

<!-- Form with states -->
<form class="space-y-4">
    <div>
        <label class="block text-sm font-medium mb-2">Email</label>
        <input type="email"
               class="w-full border-2 border-gray-300 rounded-lg px-4 py-2
                      focus:border-blue-500 focus:ring-2 focus:ring-blue-200
                      focus:outline-none transition">
    </div>
    <div>
        <label class="block text-sm font-medium mb-2">Password</label>
        <input type="password"
               class="w-full border-2 border-gray-300 rounded-lg px-4 py-2
                      focus:border-blue-500 focus:ring-2 focus:ring-blue-200
                      focus:outline-none transition">
    </div>
    <button class="w-full bg-blue-600 hover:bg-blue-700 active:bg-blue-800
                   text-white font-medium py-3 rounded-lg
                   transform hover:scale-105 active:scale-95
                   transition-all duration-150">
        Sign In
    </button>
</form>

<!-- Navigation with states -->
<nav class="flex space-x-1 bg-gray-100 p-1 rounded-lg">
    <a href="#" class="px-4 py-2 rounded bg-white shadow text-blue-600 font-medium">
        Home
    </a>
    <a href="#" class="px-4 py-2 rounded hover:bg-white hover:shadow transition text-gray-600 hover:text-gray-900">
        About
    </a>
    <a href="#" class="px-4 py-2 rounded hover:bg-white hover:shadow transition text-gray-600 hover:text-gray-900">
        Services
    </a>
    <a href="#" class="px-4 py-2 rounded hover:bg-white hover:shadow transition text-gray-600 hover:text-gray-900">
        Contact
    </a>
</nav>
Practice Tasks
  • Create a button that changes background color on hover, scales on hover (scale-105), and scales down on active (scale-95)
  • Build a card with group hover that scales the image, shows an overlay, and changes text colors
  • Design a form input with focus states that change border color and add a ring effect
  • Create a custom checkbox using peer states that changes the label's appearance when checked

Key Takeaways

  • hover:: Applies styles when hovering over an element
  • focus:: Applies styles when an element receives focus
  • active:: Applies styles when an element is being clicked
  • group-hover:: Styles child elements when hovering over a parent with class "group"
  • peer:: Styles sibling elements based on the state of a peer element
  • disabled:: Styles elements when they have the disabled attribute

What's Next?

Next Topic: Continue to Transitions & Animations to learn how to add smooth transitions and animations to your interactive elements.

Dark Mode in Tailwind CSS

Implement beautiful dark mode themes with the dark: variant

Understanding Dark Mode

Tailwind CSS includes a dark mode variant that allows you to style your site differently when dark mode is enabled. You can use either the 'media' strategy (based on system preference) or 'class' strategy (manually toggled).

Configuring Dark Mode

tailwind.config.js Setup
// tailwind.config.js
module.exports = {
  // Class strategy (manual toggle)
  darkMode: 'class',

  // OR media strategy (system preference)
  // darkMode: 'media',

  // Rest of your config...
}

Basic Dark Mode Styles

Using the dark: Variant
<!-- Background color -->
<div class="bg-white dark:bg-gray-900">
    Background changes in dark mode
</div>

<!-- Text color -->
<p class="text-gray-900 dark:text-white">
    Text color adapts to dark mode
</p>

<!-- Border color -->
<div class="border border-gray-200 dark:border-gray-700">
    Border adapts to theme
</div>

<!-- Combined styles -->
<div class="bg-white dark:bg-gray-800 text-gray-900 dark:text-white p-6 rounded-lg">
    Card that adapts to dark mode
</div>

Complete Page Example

Full Dark Mode Layout
<!-- Add dark class to html/body for dark mode -->
<html class="dark">
<body class="bg-white dark:bg-gray-900 text-gray-900 dark:text-white">

    <!-- Header -->
    <header class="bg-gray-100 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 px-6 py-4">
        <div class="container mx-auto flex items-center justify-between">
            <h1 class="text-2xl font-bold">My Site</h1>
            <button id="theme-toggle" class="p-2 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700">
                🌙
            </button>
        </div>
    </header>

    <!-- Main content -->
    <main class="container mx-auto px-6 py-8">
        <div class="bg-white dark:bg-gray-800 rounded-lg shadow-lg dark:shadow-none p-6 mb-6">
            <h2 class="text-xl font-bold mb-4">Card Title</h2>
            <p class="text-gray-600 dark:text-gray-300">
                This content adapts to light and dark modes automatically.
            </p>
        </div>
    </main>

</body>
</html>

Dark Mode Toggle Script

JavaScript Theme Switcher
// Theme toggle with localStorage
const themeToggle = document.getElementById('theme-toggle');
const html = document.documentElement;

// Check for saved theme preference or default to 'light'
const currentTheme = localStorage.getItem('theme') || 'light';
if (currentTheme === 'dark') {
    html.classList.add('dark');
}

themeToggle.addEventListener('click', () => {
    html.classList.toggle('dark');

    // Save preference
    const theme = html.classList.contains('dark') ? 'dark' : 'light';
    localStorage.setItem('theme', theme);
});

// Respect system preference on first visit
if (!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches) {
    html.classList.add('dark');
}

Common Dark Mode Patterns

Cards and Components
<!-- Card component -->
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md dark:shadow-lg dark:shadow-gray-900/30 p-6">
    <h3 class="text-xl font-bold text-gray-900 dark:text-white mb-2">
        Card Title
    </h3>
    <p class="text-gray-600 dark:text-gray-300">
        Card description text
    </p>
    <button class="mt-4 bg-blue-600 dark:bg-blue-500 hover:bg-blue-700 dark:hover:bg-blue-600 text-white px-4 py-2 rounded">
        Action Button
    </button>
</div>

<!-- Input field -->
<input type="text"
       class="w-full bg-white dark:bg-gray-800
              border border-gray-300 dark:border-gray-600
              text-gray-900 dark:text-white
              px-4 py-2 rounded-lg
              focus:border-blue-500 dark:focus:border-blue-400
              focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-800">

<!-- Navigation -->
<nav class="bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
    <div class="flex space-x-4 px-6 py-3">
        <a href="#" class="text-gray-700 dark:text-gray-200 hover:text-blue-600 dark:hover:text-blue-400">Home</a>
        <a href="#" class="text-gray-700 dark:text-gray-200 hover:text-blue-600 dark:hover:text-blue-400">About</a>
        <a href="#" class="text-gray-700 dark:text-gray-200 hover:text-blue-600 dark:hover:text-blue-400">Contact</a>
    </div>
</nav>

Dark Mode Images

Image Handling
<!-- Show different images -->
<img src="logo-light.png" class="dark:hidden">
<img src="logo-dark.png" class="hidden dark:block">

<!-- Invert images -->
<img src="icon.png" class="dark:invert">

<!-- Adjust brightness -->
<img src="photo.jpg" class="dark:brightness-75">

<!-- SVG with color change -->
<svg class="text-gray-900 dark:text-white" fill="currentColor" viewBox="0 0 20 20">
    <path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1z"></path>
</svg>

Dark Mode Color Palette

Recommended Colors
<!-- Background layers -->
<div class="bg-gray-50 dark:bg-gray-950">Page background</div>
<div class="bg-white dark:bg-gray-900">Card background</div>
<div class="bg-gray-100 dark:bg-gray-800">Secondary background</div>

<!-- Text colors -->
<p class="text-gray-900 dark:text-white">Primary text</p>
<p class="text-gray-600 dark:text-gray-300">Secondary text</p>
<p class="text-gray-400 dark:text-gray-500">Tertiary text</p>

<!-- Borders -->
<div class="border-gray-200 dark:border-gray-700">Standard border</div>
<div class="border-gray-300 dark:border-gray-600">Emphasized border</div>

<!-- Interactive elements -->
<button class="bg-blue-600 dark:bg-blue-500 hover:bg-blue-700 dark:hover:bg-blue-600">
    Primary Button
</button>
<a href="#" class="text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300">
    Link
</a>

Advanced Dark Mode Techniques

Complex Patterns
<!-- Gradient backgrounds -->
<div class="bg-gradient-to-r from-blue-500 to-purple-600 dark:from-blue-900 dark:to-purple-900">
    Gradient that adapts to dark mode
</div>

<!-- Ring colors -->
<input type="text" class="focus:ring-blue-500 dark:focus:ring-blue-400">

<!-- Placeholder text -->
<input type="text" class="placeholder-gray-400 dark:placeholder-gray-500" placeholder="Enter text...">

<!-- Divide colors -->
<div class="divide-y divide-gray-200 dark:divide-gray-700">
    <div class="py-4">Item 1</div>
    <div class="py-4">Item 2</div>
</div>

<!-- Group hover in dark mode -->
<div class="group cursor-pointer">
    <div class="bg-white dark:bg-gray-800 group-hover:bg-gray-50 dark:group-hover:bg-gray-700 p-4 rounded">
        Hover effect in both modes
    </div>
</div>

Practical Dark Mode Example

Complete Application
<!-- Dashboard with dark mode -->
<div class="min-h-screen bg-gray-50 dark:bg-gray-900">
    <!-- Sidebar -->
    <aside class="fixed left-0 top-0 h-screen w-64 bg-white dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 p-6">
        <h2 class="text-xl font-bold text-gray-900 dark:text-white mb-6">Dashboard</h2>
        <nav class="space-y-2">
            <a href="#" class="block px-4 py-2 rounded-lg bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400">
                Home
            </a>
            <a href="#" class="block px-4 py-2 rounded-lg text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700">
                Projects
            </a>
            <a href="#" class="block px-4 py-2 rounded-lg text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700">
                Settings
            </a>
        </nav>
    </aside>

    <!-- Main content -->
    <main class="ml-64 p-8">
        <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
            <div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm dark:shadow-none border border-gray-200 dark:border-gray-700 p-6">
                <p class="text-sm text-gray-600 dark:text-gray-400 mb-1">Total Users</p>
                <p class="text-3xl font-bold text-gray-900 dark:text-white">1,234</p>
            </div>
            <div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm dark:shadow-none border border-gray-200 dark:border-gray-700 p-6">
                <p class="text-sm text-gray-600 dark:text-gray-400 mb-1">Revenue</p>
                <p class="text-3xl font-bold text-gray-900 dark:text-white">$45,678</p>
            </div>
            <div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm dark:shadow-none border border-gray-200 dark:border-gray-700 p-6">
                <p class="text-sm text-gray-600 dark:text-gray-400 mb-1">Orders</p>
                <p class="text-3xl font-bold text-gray-900 dark:text-white">567</p>
            </div>
        </div>

        <div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm dark:shadow-none border border-gray-200 dark:border-gray-700 p-6">
            <h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Recent Activity</h3>
            <div class="space-y-4">
                <div class="flex items-center justify-between pb-4 border-b border-gray-200 dark:border-gray-700">
                    <div>
                        <p class="font-medium text-gray-900 dark:text-white">New user registered</p>
                        <p class="text-sm text-gray-500 dark:text-gray-400">2 minutes ago</p>
                    </div>
                </div>
            </div>
        </div>
    </main>
</div>
Practice Tasks
  • Create a complete page layout with header, main content, and footer that all adapt to dark mode
  • Build a theme toggle button that switches between light and dark modes and saves the preference
  • Design a card component with proper dark mode colors for background, text, borders, and shadows
  • Create a form with inputs that have appropriate dark mode focus states and placeholder colors

Key Takeaways

  • dark: variant: Prefix any utility with dark: to apply it in dark mode
  • Configuration: Set darkMode: 'class' in tailwind.config.js for manual toggle
  • Color strategy: Use gray-50/900 for backgrounds, gray-900/white for text
  • JavaScript toggle: Add/remove 'dark' class on html element to switch themes
  • Persistence: Use localStorage to remember user's theme preference
  • System preference: Respect prefers-color-scheme media query for first visit

What's Next?

Next Topic: Continue to Extracting Components to learn about using @apply and creating reusable components.

Spacing in Tailwind CSS

Master padding, margin, and space utilities for perfect layouts

Understanding Spacing

Tailwind provides a comprehensive spacing scale based on a consistent system. The default scale ranges from 0 to 96, where each unit corresponds to 0.25rem (4px). Spacing utilities are the foundation of layout design in Tailwind CSS.

Padding Utilities

All Sides Padding
<!-- Equal padding on all sides -->
<div class="p-4">Padding 1rem (16px) on all sides</div>
<div class="p-8">Padding 2rem (32px) on all sides</div>
<div class="p-12">Padding 3rem (48px) on all sides</div>

<!-- Different padding sizes -->
<div class="p-0">No padding</div>
<div class="p-2">Small padding (0.5rem)</div>
<div class="p-6">Medium padding (1.5rem)</div>
<div class="p-16">Large padding (4rem)</div>
Directional Padding
<!-- Individual sides -->
<div class="pt-4">Padding top</div>
<div class="pr-4">Padding right</div>
<div class="pb-4">Padding bottom</div>
<div class="pl-4">Padding left</div>

<!-- Horizontal and vertical -->
<div class="px-4">Padding left and right</div>
<div class="py-4">Padding top and bottom</div>

<!-- Combined directions -->
<div class="px-6 py-4">Different horizontal and vertical padding</div>
<div class="pt-8 pb-4 px-6">Custom padding on each axis</div>

Margin Utilities

All Sides Margin
<!-- Equal margin on all sides -->
<div class="m-4">Margin 1rem on all sides</div>
<div class="m-8">Margin 2rem on all sides</div>

<!-- Auto margin for centering -->
<div class="mx-auto">Horizontally centered</div>
<div class="mx-auto w-1/2">Centered with width constraint</div>

<!-- Negative margins -->
<div class="-m-4">Negative margin pulls element</div>
<div class="-mt-6">Negative top margin</div>
Directional Margin
<!-- Individual sides -->
<div class="mt-4">Margin top</div>
<div class="mr-4">Margin right</div>
<div class="mb-4">Margin bottom</div>
<div class="ml-4">Margin left</div>

<!-- Horizontal and vertical -->
<div class="mx-4">Margin left and right</div>
<div class="my-4">Margin top and bottom</div>

<!-- Push elements -->
<div class="ml-auto">Pushed to the right</div>
<div class="mr-auto">Pushed to the left</div>

Space Between

Spacing Between Children
<!-- Vertical spacing -->
<div class="space-y-4">
    <div class="bg-blue-500 p-4">Item 1</div>
    <div class="bg-blue-500 p-4">Item 2</div>
    <div class="bg-blue-500 p-4">Item 3</div>
</div>

<!-- Horizontal spacing -->
<div class="flex space-x-4">
    <div class="bg-green-500 p-4">Item 1</div>
    <div class="bg-green-500 p-4">Item 2</div>
    <div class="bg-green-500 p-4">Item 3</div>
</div>

<!-- Different sizes -->
<div class="space-y-8">
    <div class="bg-purple-500 p-4">Large vertical spacing</div>
    <div class="bg-purple-500 p-4">Between elements</div>
</div>

Responsive Spacing

Mobile-First Responsive Spacing
<!-- Padding changes with breakpoints -->
<div class="p-4 md:p-8 lg:p-12">
    Small padding on mobile, increases on larger screens
</div>

<!-- Margin changes with breakpoints -->
<div class="m-2 sm:m-4 md:m-6 lg:m-8">
    Margin scales up with screen size
</div>

<!-- Responsive space between -->
<div class="space-y-2 md:space-y-4 lg:space-y-6">
    <div class="bg-red-500 p-4">Item 1</div>
    <div class="bg-red-500 p-4">Item 2</div>
    <div class="bg-red-500 p-4">Item 3</div>
</div>

<!-- Responsive centering -->
<div class="mx-4 md:mx-auto md:w-3/4 lg:w-1/2">
    Full width on mobile, centered and constrained on larger screens
</div>

Spacing Scale Reference

Common Spacing Values
/* Tailwind Spacing Scale */
0   = 0px
0.5 = 0.125rem (2px)
1   = 0.25rem  (4px)
2   = 0.5rem   (8px)
3   = 0.75rem  (12px)
4   = 1rem     (16px)
5   = 1.25rem  (20px)
6   = 1.5rem   (24px)
8   = 2rem     (32px)
10  = 2.5rem   (40px)
12  = 3rem     (48px)
16  = 4rem     (64px)
20  = 5rem     (80px)
24  = 6rem     (96px)
32  = 8rem     (128px)
40  = 10rem    (160px)
48  = 12rem    (192px)

Practical Spacing Examples

Real-World Layouts
<!-- Card with proper spacing -->
<div class="bg-white rounded-lg shadow-md p-6 m-4">
    <h2 class="text-2xl font-bold mb-4">Card Title</h2>
    <p class="text-gray-600 mb-6">Card content with proper spacing</p>
    <button class="bg-blue-500 text-white px-6 py-2 rounded">Action</button>
</div>

<!-- Navigation with spacing -->
<nav class="bg-gray-800 px-6 py-4">
    <div class="flex space-x-8">
        <a href="#" class="text-white">Home</a>
        <a href="#" class="text-white">About</a>
        <a href="#" class="text-white">Services</a>
        <a href="#" class="text-white">Contact</a>
    </div>
</nav>

<!-- Form with vertical spacing -->
<form class="space-y-4">
    <div>
        <label class="block mb-2">Name</label>
        <input type="text" class="w-full px-4 py-2 border rounded">
    </div>
    <div>
        <label class="block mb-2">Email</label>
        <input type="email" class="w-full px-4 py-2 border rounded">
    </div>
    <button class="px-6 py-2 bg-blue-500 text-white rounded">Submit</button>
</form>
Practice Tasks
  • Create a card component with consistent internal padding (p-6) and proper spacing between heading, content, and button (mb-4, mb-6)
  • Build a navigation bar with horizontal spacing between menu items using space-x utilities
  • Design a form with vertical spacing between input fields that increases on larger screens (space-y-4 md:space-y-6)
  • Create a centered container using mx-auto with responsive padding (px-4 md:px-8 lg:px-12)

Key Takeaways

  • p-{size}: Adds padding on all sides; use pt, pr, pb, pl for specific sides
  • m-{size}: Adds margin on all sides; use mt, mr, mb, ml for specific sides
  • px/py: Shorthand for horizontal (left+right) or vertical (top+bottom) spacing
  • space-x/space-y: Adds consistent spacing between child elements
  • mx-auto: Centers an element horizontally with automatic left and right margins
  • Negative values: Use negative margins (e.g., -mt-4) to pull elements closer or create overlaps

What's Next?

Next Topic: Continue to Sizing to learn about width, height, and size utilities in Tailwind CSS.

Sizing in Tailwind CSS

Control element dimensions with width, height, and size utilities

Understanding Sizing

Tailwind provides a comprehensive set of utilities for controlling the width and height of elements. These include fixed sizes, percentage-based sizes, viewport units, and responsive sizing options.

Width Utilities

Fixed and Fractional Widths
<!-- Fixed width in rem -->
<div class="w-64">Width of 16rem (256px)</div>
<div class="w-96">Width of 24rem (384px)</div>

<!-- Fractional widths -->
<div class="w-1/2">50% width</div>
<div class="w-1/3">33.333% width</div>
<div class="w-2/3">66.666% width</div>
<div class="w-1/4">25% width</div>
<div class="w-3/4">75% width</div>

<!-- Full width -->
<div class="w-full">100% width</div>

<!-- Screen width -->
<div class="w-screen">100vw width</div>
Auto and Min/Max Widths
<!-- Auto width (content size) -->
<div class="w-auto">Width based on content</div>

<!-- Min and max widths -->
<div class="min-w-0">Minimum width 0</div>
<div class="min-w-full">Minimum width 100%</div>
<div class="max-w-xs">Max width 20rem (320px)</div>
<div class="max-w-sm">Max width 24rem (384px)</div>
<div class="max-w-md">Max width 28rem (448px)</div>
<div class="max-w-lg">Max width 32rem (512px)</div>
<div class="max-w-xl">Max width 36rem (576px)</div>
<div class="max-w-2xl">Max width 42rem (672px)</div>
<div class="max-w-4xl">Max width 56rem (896px)</div>
<div class="max-w-full">Max width 100%</div>

Height Utilities

Fixed and Fractional Heights
<!-- Fixed height in rem -->
<div class="h-32">Height of 8rem (128px)</div>
<div class="h-64">Height of 16rem (256px)</div>

<!-- Fractional heights -->
<div class="h-1/2">50% height</div>
<div class="h-1/3">33.333% height</div>
<div class="h-2/3">66.666% height</div>

<!-- Full height -->
<div class="h-full">100% height</div>

<!-- Screen height -->
<div class="h-screen">100vh height</div>
Min and Max Heights
<!-- Minimum heights -->
<div class="min-h-0">Minimum height 0</div>
<div class="min-h-full">Minimum height 100%</div>
<div class="min-h-screen">Minimum height 100vh</div>

<!-- Maximum heights -->
<div class="max-h-screen">Maximum height 100vh</div>
<div class="max-h-full">Maximum height 100%</div>
<div class="max-h-96">Maximum height 24rem</div>

<!-- Scrollable container with max height -->
<div class="max-h-64 overflow-y-auto">
    Long content that scrolls...
</div>

Responsive Sizing

Mobile-First Responsive Sizes
<!-- Width changes with breakpoints -->
<div class="w-full md:w-1/2 lg:w-1/3">
    Full width on mobile, half on tablet, third on desktop
</div>

<!-- Height changes with breakpoints -->
<div class="h-64 md:h-96 lg:h-screen">
    Height increases with screen size
</div>

<!-- Max width responsive -->
<div class="max-w-sm md:max-w-2xl lg:max-w-4xl">
    Max width expands on larger screens
</div>

<!-- Container with responsive width -->
<div class="w-full sm:w-11/12 md:w-4/5 lg:w-3/4 xl:w-2/3">
    Progressive width constraints
</div>

Size Utilities (Width and Height)

Square and Consistent Sizing
<!-- Square elements using size -->
<div class="size-12">48px × 48px square</div>
<div class="size-16">64px × 64px square</div>
<div class="size-24">96px × 96px square</div>

<!-- Icons and avatars -->
<img src="avatar.jpg" class="size-10 rounded-full">
<div class="size-8 bg-blue-500 rounded"></div>

<!-- Size with arbitrary values -->
<div class="size-[200px]">200px × 200px</div>

Viewport Units

Using Viewport Width and Height
<!-- Full screen hero section -->
<section class="w-screen h-screen bg-gradient-to-r from-blue-500 to-purple-600">
    <div class="flex items-center justify-center h-full">
        <h1 class="text-white text-5xl">Full Screen Hero</h1>
    </div>
</section>

<!-- Minimum height of viewport -->
<div class="min-h-screen flex flex-col">
    <header class="bg-gray-800 text-white p-4">Header</header>
    <main class="flex-1 bg-gray-100 p-8">Content</main>
    <footer class="bg-gray-800 text-white p-4">Footer</footer>
</div>

<!-- Sidebar with screen height -->
<aside class="w-64 h-screen bg-gray-800 text-white p-4">
    Sidebar content
</aside>

Practical Sizing Examples

Real-World Layouts
<!-- Card with constrained width -->
<div class="max-w-sm mx-auto bg-white rounded-lg shadow-md">
    <img src="image.jpg" class="w-full h-48 object-cover rounded-t-lg">
    <div class="p-6">
        <h2 class="text-xl font-bold mb-2">Card Title</h2>
        <p class="text-gray-600">Card content...</p>
    </div>
</div>

<!-- Responsive grid items -->
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
    <div class="bg-blue-500 h-32 md:h-48"></div>
    <div class="bg-blue-500 h-32 md:h-48"></div>
    <div class="bg-blue-500 h-32 md:h-48"></div>
    <div class="bg-blue-500 h-32 md:h-48"></div>
</div>

<!-- Content container with max width -->
<article class="max-w-4xl mx-auto px-4 py-8">
    <h1 class="text-3xl font-bold mb-4">Article Title</h1>
    <p class="text-gray-700 leading-relaxed">Article content...</p>
</article>

<!-- Modal with constrained dimensions -->
<div class="fixed inset-0 flex items-center justify-center">
    <div class="bg-white w-full max-w-md max-h-screen overflow-y-auto p-6 rounded-lg">
        Modal content
    </div>
</div>
Practice Tasks
  • Create a hero section that takes up the full viewport height (h-screen) with centered content
  • Build a card grid where cards are full width on mobile but constrained to max-w-sm on larger screens
  • Design a sidebar layout with a fixed width sidebar (w-64) and a flexible main content area (flex-1)
  • Create a responsive image gallery where images are h-32 on mobile, h-48 on tablet, and h-64 on desktop

Key Takeaways

  • w-{size}: Sets width using rem units, fractions (1/2, 1/3), full, or screen
  • h-{size}: Sets height using rem units, fractions, full, or screen
  • size-{n}: Sets both width and height to the same value (useful for squares)
  • min-w/max-w: Controls minimum and maximum widths for responsive constraints
  • min-h/max-h: Controls minimum and maximum heights
  • w-screen/h-screen: Makes element 100vw/100vh (full viewport)

What's Next?

Next Topic: Continue to Colors to learn about Tailwind's comprehensive color system and utilities.

Colors in Tailwind CSS

Master the comprehensive color palette and color utilities

Understanding Tailwind Colors

Tailwind includes a carefully crafted color palette with multiple shades (50-900) for each color. These colors can be applied to text, backgrounds, borders, and more. The palette is designed to provide visual consistency and accessibility.

Text Colors

Basic Text Colors
<!-- Gray scale -->
<p class="text-gray-900">Very dark gray (almost black)</p>
<p class="text-gray-700">Dark gray</p>
<p class="text-gray-500">Medium gray</p>
<p class="text-gray-300">Light gray</p>

<!-- Primary colors -->
<p class="text-blue-600">Blue text</p>
<p class="text-red-600">Red text</p>
<p class="text-green-600">Green text</p>
<p class="text-yellow-600">Yellow text</p>
<p class="text-purple-600">Purple text</p>
<p class="text-pink-600">Pink text</p>

<!-- Special colors -->
<p class="text-black">Pure black</p>
<p class="text-white">Pure white</p>
Text Color Shades
<!-- Light to dark progression -->
<p class="text-blue-50">Lightest blue</p>
<p class="text-blue-100">Very light blue</p>
<p class="text-blue-200">Light blue</p>
<p class="text-blue-300">Medium-light blue</p>
<p class="text-blue-400">Medium blue</p>
<p class="text-blue-500">Base blue</p>
<p class="text-blue-600">Medium-dark blue</p>
<p class="text-blue-700">Dark blue</p>
<p class="text-blue-800">Darker blue</p>
<p class="text-blue-900">Darkest blue</p>

Background Colors

Basic Background Colors
<!-- Solid backgrounds -->
<div class="bg-blue-500 text-white p-4">Blue background</div>
<div class="bg-green-500 text-white p-4">Green background</div>
<div class="bg-red-500 text-white p-4">Red background</div>
<div class="bg-yellow-500 text-black p-4">Yellow background</div>

<!-- Light backgrounds for sections -->
<section class="bg-gray-50 p-8">
    <h2 class="text-gray-900">Light gray section</h2>
</section>

<!-- Dark backgrounds -->
<div class="bg-gray-900 text-white p-8">
    Dark background with white text
</div>
Background Opacity
<!-- Background with opacity -->
<div class="bg-blue-500/50 p-4">50% opacity blue</div>
<div class="bg-blue-500/75 p-4">75% opacity blue</div>
<div class="bg-blue-500/100 p-4">100% opacity blue</div>

<!-- Semi-transparent overlays -->
<div class="relative">
    <img src="image.jpg" class="w-full">
    <div class="absolute inset-0 bg-black/50 flex items-center justify-center">
        <h2 class="text-white text-3xl">Overlay Text</h2>
    </div>
</div>

Border Colors

Border Color Utilities
<!-- Basic border colors -->
<div class="border-2 border-blue-500 p-4">Blue border</div>
<div class="border-2 border-red-500 p-4">Red border</div>
<div class="border-2 border-green-500 p-4">Green border</div>

<!-- Different border sides -->
<div class="border-t-4 border-blue-500 p-4">Top blue border</div>
<div class="border-b-4 border-red-500 p-4">Bottom red border</div>
<div class="border-l-4 border-green-500 p-4">Left green border</div>

<!-- Border with opacity -->
<div class="border-2 border-purple-500/50 p-4">Semi-transparent border</div>

Color Palette Overview

Available Color Families
<!-- Slate (cool gray) -->
<div class="bg-slate-500">Slate</div>

<!-- Gray (neutral gray) -->
<div class="bg-gray-500">Gray</div>

<!-- Zinc (warm gray) -->
<div class="bg-zinc-500">Zinc</div>

<!-- Red -->
<div class="bg-red-500">Red</div>

<!-- Orange -->
<div class="bg-orange-500">Orange</div>

<!-- Amber -->
<div class="bg-amber-500">Amber</div>

<!-- Yellow -->
<div class="bg-yellow-500">Yellow</div>

<!-- Lime -->
<div class="bg-lime-500">Lime</div>

<!-- Green -->
<div class="bg-green-500">Green</div>

<!-- Emerald -->
<div class="bg-emerald-500">Emerald</div>

<!-- Teal -->
<div class="bg-teal-500">Teal</div>

<!-- Cyan -->
<div class="bg-cyan-500">Cyan</div>

<!-- Sky -->
<div class="bg-sky-500">Sky</div>

<!-- Blue -->
<div class="bg-blue-500">Blue</div>

<!-- Indigo -->
<div class="bg-indigo-500">Indigo</div>

<!-- Violet -->
<div class="bg-violet-500">Violet</div>

<!-- Purple -->
<div class="bg-purple-500">Purple</div>

<!-- Fuchsia -->
<div class="bg-fuchsia-500">Fuchsia</div>

<!-- Pink -->
<div class="bg-pink-500">Pink</div>

<!-- Rose -->
<div class="bg-rose-500">Rose</div>

Responsive Colors

Breakpoint-Based Colors
<!-- Text color changes -->
<h1 class="text-blue-600 md:text-purple-600 lg:text-green-600">
    Color changes at different breakpoints
</h1>

<!-- Background color changes -->
<div class="bg-gray-100 md:bg-blue-100 lg:bg-green-100 p-8">
    Background adapts to screen size
</div>

<!-- Border color changes -->
<button class="border-2 border-blue-500 md:border-red-500 lg:border-green-500 p-4">
    Border color varies
</button>

Practical Color Examples

Real-World Color Usage
<!-- Alert components -->
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4">
    <p class="font-bold">Error</p>
    <p>Something went wrong.</p>
</div>

<div class="bg-yellow-100 border-l-4 border-yellow-500 text-yellow-700 p-4">
    <p class="font-bold">Warning</p>
    <p>Please check this.</p>
</div>

<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4">
    <p class="font-bold">Success</p>
    <p>Operation completed.</p>
</div>

<!-- Button variations -->
<button class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded">
    Primary Button
</button>
<button class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-6 py-2 rounded">
    Secondary Button
</button>
<button class="bg-red-600 hover:bg-red-700 text-white px-6 py-2 rounded">
    Danger Button
</button>

<!-- Card with color accents -->
<div class="bg-white border-t-4 border-blue-500 rounded-lg shadow-md p-6">
    <h3 class="text-blue-600 font-bold text-xl mb-2">Card Title</h3>
    <p class="text-gray-600">Card content with color accents.</p>
</div>

<!-- Badge components -->
<span class="bg-blue-100 text-blue-800 px-3 py-1 rounded-full text-sm">New</span>
<span class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm">Active</span>
<span class="bg-red-100 text-red-800 px-3 py-1 rounded-full text-sm">Urgent</span>
Practice Tasks
  • Create alert components for success, warning, error, and info using appropriate color combinations
  • Build a set of status badges (new, active, pending, completed) with distinct background and text colors
  • Design a card with a colored top border accent and matching text colors for headings
  • Create a button group with primary (blue), secondary (gray), and danger (red) variants

Key Takeaways

  • text-{color}-{shade}: Sets text color with shades from 50 (lightest) to 900 (darkest)
  • bg-{color}-{shade}: Sets background color using the same shade system
  • border-{color}-{shade}: Sets border color for all sides or specific sides
  • Opacity: Use /{opacity} (e.g., bg-blue-500/50) for semi-transparent colors
  • Color families: Tailwind includes 22 color families with 10 shades each
  • Consistency: Use the same color family with different shades for visual harmony

What's Next?

Next Topic: Continue to Typography to learn about text styling, fonts, and type utilities in Tailwind CSS.

Typography in Tailwind CSS

Complete control over text styling, fonts, and readability

Understanding Typography

Typography utilities in Tailwind allow you to control every aspect of text appearance, including font family, size, weight, line height, letter spacing, text alignment, and more. These utilities make it easy to create beautiful, readable text layouts.

Font Family

Font Family Utilities
<!-- Sans-serif (default) -->
<p class="font-sans">
    The quick brown fox jumps over the lazy dog.
</p>

<!-- Serif -->
<p class="font-serif">
    The quick brown fox jumps over the lazy dog.
</p>

<!-- Monospace -->
<p class="font-mono">
    The quick brown fox jumps over the lazy dog.
</p>

<!-- Common usage -->
<article class="font-serif">
    <h1 class="font-sans">Article Title</h1>
    <p>Body text in serif for readability...</p>
    <code class="font-mono">console.log('code')</code>
</article>

Font Size

Text Size Scale
<!-- Extra small to extra large -->
<p class="text-xs">Extra small text (0.75rem / 12px)</p>
<p class="text-sm">Small text (0.875rem / 14px)</p>
<p class="text-base">Base text (1rem / 16px)</p>
<p class="text-lg">Large text (1.125rem / 18px)</p>
<p class="text-xl">Extra large text (1.25rem / 20px)</p>

<!-- Heading sizes -->
<h1 class="text-6xl">Heading 1 (3.75rem / 60px)</h1>
<h2 class="text-5xl">Heading 2 (3rem / 48px)</h2>
<h3 class="text-4xl">Heading 3 (2.25rem / 36px)</h3>
<h4 class="text-3xl">Heading 4 (1.875rem / 30px)</h4>
<h5 class="text-2xl">Heading 5 (1.5rem / 24px)</h5>
<h6 class="text-xl">Heading 6 (1.25rem / 20px)</h6>

<!-- Giant sizes for hero sections -->
<h1 class="text-7xl">Huge (4.5rem / 72px)</h1>
<h1 class="text-8xl">Giant (6rem / 96px)</h1>
<h1 class="text-9xl">Massive (8rem / 128px)</h1>

Font Weight

Font Weight Variations
<!-- Weight scale -->
<p class="font-thin">Thin (100)</p>
<p class="font-extralight">Extra Light (200)</p>
<p class="font-light">Light (300)</p>
<p class="font-normal">Normal (400)</p>
<p class="font-medium">Medium (500)</p>
<p class="font-semibold">Semi Bold (600)</p>
<p class="font-bold">Bold (700)</p>
<p class="font-extrabold">Extra Bold (800)</p>
<p class="font-black">Black (900)</p>

<!-- Common usage -->
<h2 class="font-bold">Heading</h2>
<p class="font-normal">Body text</p>
<span class="font-medium">Emphasized text</span>

Line Height

Controlling Line Height
<!-- Relative line heights -->
<p class="leading-none">Line height 1 (very tight)</p>
<p class="leading-tight">Line height 1.25</p>
<p class="leading-snug">Line height 1.375</p>
<p class="leading-normal">Line height 1.5 (default)</p>
<p class="leading-relaxed">Line height 1.625</p>
<p class="leading-loose">Line height 2</p>

<!-- Fixed line heights -->
<p class="leading-3">Line height 0.75rem</p>
<p class="leading-6">Line height 1.5rem</p>
<p class="leading-10">Line height 2.5rem</p>

<!-- Practical example -->
<article class="leading-relaxed">
    <h1 class="leading-tight">Article Title</h1>
    <p>Body text with relaxed line height for better readability...</p>
</article>

Text Alignment

Horizontal Alignment
<!-- Basic alignment -->
<p class="text-left">Left aligned text</p>
<p class="text-center">Center aligned text</p>
<p class="text-right">Right aligned text</p>
<p class="text-justify">Justified text spreads across the full width</p>

<!-- Responsive alignment -->
<h1 class="text-center md:text-left">
    Centered on mobile, left-aligned on desktop
</h1>

<!-- Start and end (useful for RTL) -->
<p class="text-start">Start aligned</p>
<p class="text-end">End aligned</p>

Text Decoration and Transform

Text Styling
<!-- Text decoration -->
<p class="underline">Underlined text</p>
<p class="overline">Overlined text</p>
<p class="line-through">Strikethrough text</p>
<p class="no-underline">Remove underline</p>

<!-- Text transform -->
<p class="uppercase">UPPERCASE TEXT</p>
<p class="lowercase">lowercase text</p>
<p class="capitalize">Capitalize Each Word</p>
<p class="normal-case">Normal case</p>

<!-- Font style -->
<p class="italic">Italic text</p>
<p class="not-italic">Not italic</p>

<!-- Common usage -->
<a href="#" class="underline text-blue-600 hover:no-underline">Link</a>
<button class="uppercase font-semibold">Submit</button>

Letter Spacing and Word Spacing

Tracking and Spacing
<!-- Letter spacing (tracking) -->
<p class="tracking-tighter">Tighter letter spacing</p>
<p class="tracking-tight">Tight letter spacing</p>
<p class="tracking-normal">Normal letter spacing</p>
<p class="tracking-wide">Wide letter spacing</p>
<p class="tracking-wider">Wider letter spacing</p>
<p class="tracking-widest">Widest letter spacing</p>

<!-- Common usage -->
<h1 class="uppercase tracking-widest">SPACED HEADING</h1>
<p class="tracking-tight">Compact paragraph text</p>

Practical Typography Examples

Complete Typography Patterns
<!-- Hero section typography -->
<section class="text-center py-20">
    <h1 class="text-5xl md:text-6xl lg:text-7xl font-bold mb-4">
        Welcome to Our Platform
    </h1>
    <p class="text-xl md:text-2xl text-gray-600 font-light leading-relaxed">
        Build amazing things with Tailwind CSS
    </p>
</section>

<!-- Article typography -->
<article class="max-w-2xl mx-auto px-4">
    <h1 class="text-4xl font-bold mb-4 leading-tight">Article Title</h1>
    <p class="text-gray-500 text-sm mb-8">Published on May 15, 2024</p>

    <div class="prose prose-lg">
        <p class="text-lg leading-relaxed text-gray-700 mb-4">
            This is the introduction paragraph with larger text...
        </p>

        <h2 class="text-2xl font-bold mt-8 mb-4">Subheading</h2>
        <p class="leading-relaxed text-gray-600">
            Regular body text with comfortable line height...
        </p>
    </div>
</article>

<!-- Card with typography -->
<div class="bg-white rounded-lg shadow-md p-6">
    <h3 class="text-xl font-semibold mb-2">Card Title</h3>
    <p class="text-sm text-gray-500 uppercase tracking-wider mb-4">Category</p>
    <p class="text-gray-700 leading-relaxed">Card description text...</p>
</div>

<!-- Button typography -->
<button class="px-6 py-3 bg-blue-600 text-white font-medium uppercase tracking-wide rounded-lg">
    Get Started
</button>
Practice Tasks
  • Create a hero section with a large bold heading (text-6xl font-bold) and a lighter subheading (text-2xl font-light)
  • Build an article layout with proper heading hierarchy (text-4xl, text-2xl, text-xl) and comfortable body text (leading-relaxed)
  • Design a card component with an uppercase category label (uppercase tracking-widest) and normal body text
  • Create a button with medium weight text (font-medium) and wide letter spacing (tracking-wide) for better readability

Key Takeaways

  • font-{family}: Controls font family (sans, serif, mono)
  • text-{size}: Sets font size from xs to 9xl
  • font-{weight}: Controls font weight from thin to black
  • leading-{height}: Adjusts line height for readability
  • tracking-{spacing}: Controls letter spacing (tracking)
  • text-{align}: Sets text alignment (left, center, right, justify)

What's Next?

Next Topic: Continue to Backgrounds to learn about background colors, gradients, and images in Tailwind CSS.

Backgrounds in Tailwind CSS

Style backgrounds with colors, gradients, images, and patterns

Understanding Backgrounds

Tailwind provides extensive utilities for controlling background colors, gradients, images, positioning, size, and repeat patterns. These utilities make it easy to create visually appealing backgrounds for any element.

Background Colors

Solid Background Colors
<!-- Basic colors -->
<div class="bg-blue-500 p-4">Blue background</div>
<div class="bg-red-500 p-4">Red background</div>
<div class="bg-green-500 p-4">Green background</div>

<!-- Shades -->
<div class="bg-gray-100 p-4">Very light gray</div>
<div class="bg-gray-500 p-4">Medium gray</div>
<div class="bg-gray-900 p-4">Very dark gray</div>

<!-- Transparent -->
<div class="bg-transparent p-4">Transparent background</div>

<!-- With opacity -->
<div class="bg-blue-500/50 p-4">50% opacity blue</div>
<div class="bg-red-500/75 p-4">75% opacity red</div>

Linear Gradients

Gradient Backgrounds
<!-- Basic gradients with direction -->
<div class="bg-gradient-to-r from-blue-500 to-purple-500 p-8">
    Left to right gradient
</div>

<div class="bg-gradient-to-l from-blue-500 to-purple-500 p-8">
    Right to left gradient
</div>

<div class="bg-gradient-to-t from-blue-500 to-purple-500 p-8">
    Bottom to top gradient
</div>

<div class="bg-gradient-to-b from-blue-500 to-purple-500 p-8">
    Top to bottom gradient
</div>

<!-- Diagonal gradients -->
<div class="bg-gradient-to-br from-blue-500 to-purple-500 p-8">
    Top-left to bottom-right
</div>

<div class="bg-gradient-to-tr from-blue-500 to-purple-500 p-8">
    Bottom-left to top-right
</div>
Multi-Color Gradients
<!-- Three color gradient -->
<div class="bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500 p-8">
    Blue to purple to pink
</div>

<!-- Multiple via colors -->
<div class="bg-gradient-to-r from-red-500 via-yellow-500 via-green-500 to-blue-500 p-8">
    Rainbow gradient
</div>

<!-- Gradient with transparency -->
<div class="bg-gradient-to-r from-blue-500/50 to-purple-500/50 p-8">
    Semi-transparent gradient
</div>

Background Images

Background Image Utilities
<!-- Background image with arbitrary value -->
<div class="bg-[url('/images/hero.jpg')] bg-cover bg-center h-64">
    Content over background image
</div>

<!-- With overlay -->
<div class="relative bg-[url('/images/hero.jpg')] bg-cover bg-center h-64">
    <div class="absolute inset-0 bg-black/50"></div>
    <div class="relative text-white p-8">
        Content with dark overlay
    </div>
</div>

<!-- Gradient overlay on image -->
<div class="relative bg-[url('/images/hero.jpg')] bg-cover bg-center h-96">
    <div class="absolute inset-0 bg-gradient-to-t from-black/75 to-transparent"></div>
    <div class="relative h-full flex items-end p-8">
        <h2 class="text-white text-4xl font-bold">Title at Bottom</h2>
    </div>
</div>

Background Size

Controlling Background Size
<!-- Auto size -->
<div class="bg-[url('/image.jpg')] bg-auto h-64"></div>

<!-- Cover (fills entire element) -->
<div class="bg-[url('/image.jpg')] bg-cover h-64">
    Background covers entire area
</div>

<!-- Contain (fits within element) -->
<div class="bg-[url('/image.jpg')] bg-contain h-64">
    Background fits within area
</div>

<!-- Custom size -->
<div class="bg-[url('/image.jpg')] bg-[length:200px_100px] h-64">
    Custom background size
</div>

Background Position

Positioning Backgrounds
<!-- Position keywords -->
<div class="bg-[url('/image.jpg')] bg-center bg-cover h-64">Center</div>
<div class="bg-[url('/image.jpg')] bg-top bg-cover h-64">Top</div>
<div class="bg-[url('/image.jpg')] bg-bottom bg-cover h-64">Bottom</div>
<div class="bg-[url('/image.jpg')] bg-left bg-cover h-64">Left</div>
<div class="bg-[url('/image.jpg')] bg-right bg-cover h-64">Right</div>

<!-- Corner positions -->
<div class="bg-[url('/image.jpg')] bg-left-top bg-cover h-64">Top Left</div>
<div class="bg-[url('/image.jpg')] bg-right-bottom bg-cover h-64">Bottom Right</div>

<!-- Custom position -->
<div class="bg-[url('/image.jpg')] bg-[center_top_1rem] bg-cover h-64">
    Custom position
</div>

Background Repeat

Repeat Patterns
<!-- Repeat options -->
<div class="bg-[url('/pattern.png')] bg-repeat h-64">
    Repeats in both directions (default)
</div>

<div class="bg-[url('/pattern.png')] bg-no-repeat h-64">
    No repeat
</div>

<div class="bg-[url('/pattern.png')] bg-repeat-x h-64">
    Repeats horizontally only
</div>

<div class="bg-[url('/pattern.png')] bg-repeat-y h-64">
    Repeats vertically only
</div>

<div class="bg-[url('/pattern.png')] bg-repeat-round h-64">
    Repeats and scales to fit
</div>

<div class="bg-[url('/pattern.png')] bg-repeat-space h-64">
    Repeats with spacing
</div>

Background Attachment

Scroll Behavior
<!-- Fixed background (parallax effect) -->
<div class="bg-[url('/hero.jpg')] bg-fixed bg-cover h-screen">
    Background stays fixed while scrolling
</div>

<!-- Local scroll -->
<div class="bg-[url('/pattern.png')] bg-local bg-repeat h-64 overflow-scroll">
    Background scrolls with content
</div>

<!-- Scroll (default) -->
<div class="bg-[url('/hero.jpg')] bg-scroll bg-cover h-64">
    Background scrolls normally
</div>

Practical Background Examples

Real-World Patterns
<!-- Hero section with gradient -->
<section class="bg-gradient-to-r from-blue-600 to-purple-600 text-white py-20">
    <div class="container mx-auto px-4 text-center">
        <h1 class="text-5xl font-bold mb-4">Welcome</h1>
        <p class="text-xl">Beautiful gradient background</p>
    </div>
</section>

<!-- Card with subtle background -->
<div class="bg-gray-50 rounded-lg p-6 shadow-md">
    <h3 class="text-xl font-bold mb-2">Card Title</h3>
    <p class="text-gray-600">Subtle gray background</p>
</div>

<!-- Image card with overlay -->
<div class="relative h-64 rounded-lg overflow-hidden">
    <div class="absolute inset-0 bg-[url('/card-bg.jpg')] bg-cover bg-center"></div>
    <div class="absolute inset-0 bg-gradient-to-t from-black/75 via-black/25 to-transparent"></div>
    <div class="relative h-full flex flex-col justify-end p-6 text-white">
        <h3 class="text-2xl font-bold">Card Title</h3>
        <p>Description text</p>
    </div>
</div>

<!-- Testimonial with pattern -->
<div class="bg-gradient-to-br from-blue-500 to-purple-600 p-8 rounded-lg">
    <p class="text-white text-lg italic mb-4">
        "Amazing product! Highly recommended."
    </p>
    <p class="text-white/80">- Customer Name</p>
</div>

<!-- Parallax section -->
<section class="bg-[url('/parallax.jpg')] bg-fixed bg-cover bg-center py-32">
    <div class="bg-white/90 max-w-2xl mx-auto p-8 rounded-lg">
        <h2 class="text-3xl font-bold mb-4">Parallax Effect</h2>
        <p>Background image stays fixed while scrolling</p>
    </div>
</section>
Practice Tasks
  • Create a hero section with a gradient background (bg-gradient-to-r from-blue-600 to-purple-600) and white text
  • Build a card with a background image, dark overlay (bg-black/50), and content positioned at the bottom
  • Design a parallax section using bg-fixed with a background image that stays in place while scrolling
  • Create a pattern background using bg-repeat with a small repeating image

Key Takeaways

  • bg-{color}: Sets solid background color with optional opacity (/50, /75, etc.)
  • bg-gradient-to-{direction}: Creates linear gradients (r, l, t, b, tr, br, etc.)
  • from/via/to: Defines gradient color stops for multi-color gradients
  • bg-cover/contain: Controls how background images are sized
  • bg-{position}: Sets background image position (center, top, bottom, etc.)
  • bg-fixed: Creates parallax effects by fixing background during scroll

What's Next?

Next Topic: Continue to Borders to learn about border styles, widths, colors, and radius in Tailwind CSS.

Borders in Tailwind CSS

Style borders with width, color, radius, and style utilities

Understanding Borders

Tailwind provides comprehensive border utilities for controlling width, color, style, and radius. These utilities can be applied to all sides or individual sides of an element, giving you complete control over border appearance.

Border Width

Basic Border Widths
<!-- All sides -->
<div class="border">Default border (1px)</div>
<div class="border-0">No border</div>
<div class="border-2">2px border</div>
<div class="border-4">4px border</div>
<div class="border-8">8px border</div>

<!-- Individual sides -->
<div class="border-t-4">Top border only</div>
<div class="border-r-4">Right border only</div>
<div class="border-b-4">Bottom border only</div>
<div class="border-l-4">Left border only</div>

<!-- Horizontal and vertical -->
<div class="border-x-4">Left and right borders</div>
<div class="border-y-4">Top and bottom borders</div>
Mixed Border Widths
<!-- Different widths on different sides -->
<div class="border-t-4 border-b-2 border-x">
    Thick top, medium bottom, thin sides
</div>

<!-- Accent borders -->
<div class="border-l-4 border-t border-r border-b">
    Thick left border accent
</div>

<!-- Card with top accent -->
<div class="border-t-4 border-blue-500 border-x border-b bg-white p-6">
    Card with colored top accent
</div>

Border Colors

Basic Border Colors
<!-- Solid colors -->
<div class="border-2 border-blue-500">Blue border</div>
<div class="border-2 border-red-500">Red border</div>
<div class="border-2 border-green-500">Green border</div>

<!-- Different shades -->
<div class="border-2 border-gray-200">Light gray border</div>
<div class="border-2 border-gray-500">Medium gray border</div>
<div class="border-2 border-gray-900">Dark gray border</div>

<!-- With opacity -->
<div class="border-2 border-blue-500/50">50% opacity border</div>
<div class="border-2 border-red-500/75">75% opacity border</div>
Individual Side Colors
<!-- Different colors on different sides -->
<div class="border-t-4 border-t-blue-500
            border-r-4 border-r-red-500
            border-b-4 border-b-green-500
            border-l-4 border-l-yellow-500 p-4">
    Rainbow borders
</div>

<!-- Accent with default sides -->
<div class="border border-gray-300 border-l-4 border-l-blue-600 p-4">
    Left accent with subtle other borders
</div>

Border Radius

Rounded Corners
<!-- All corners -->
<div class="rounded-none">No rounding (square)</div>
<div class="rounded-sm">Small rounding (0.125rem)</div>
<div class="rounded">Default rounding (0.25rem)</div>
<div class="rounded-md">Medium rounding (0.375rem)</div>
<div class="rounded-lg">Large rounding (0.5rem)</div>
<div class="rounded-xl">Extra large (0.75rem)</div>
<div class="rounded-2xl">2XL rounding (1rem)</div>
<div class="rounded-3xl">3XL rounding (1.5rem)</div>
<div class="rounded-full">Fully rounded (9999px)</div>

<!-- Circles and pills -->
<div class="w-24 h-24 rounded-full bg-blue-500">Circle</div>
<button class="rounded-full px-6 py-2 bg-blue-500">Pill Button</button>
Individual Corner Radius
<!-- Specific corners -->
<div class="rounded-tl-lg">Top-left rounded</div>
<div class="rounded-tr-lg">Top-right rounded</div>
<div class="rounded-br-lg">Bottom-right rounded</div>
<div class="rounded-bl-lg">Bottom-left rounded</div>

<!-- Sides -->
<div class="rounded-t-lg">Top corners rounded</div>
<div class="rounded-r-lg">Right corners rounded</div>
<div class="rounded-b-lg">Bottom corners rounded</div>
<div class="rounded-l-lg">Left corners rounded</div>

<!-- Tabs with rounded tops -->
<div class="rounded-t-lg border border-b-0 px-4 py-2 bg-white">
    Tab
</div>

Border Style

Border Styles
<!-- Different border styles -->
<div class="border-2 border-solid border-gray-500">
    Solid border (default)
</div>

<div class="border-2 border-dashed border-gray-500">
    Dashed border
</div>

<div class="border-2 border-dotted border-gray-500">
    Dotted border
</div>

<div class="border-2 border-double border-gray-500">
    Double border
</div>

<div class="border-2 border-none">
    No border
</div>

<!-- Dashed dividers -->
<div class="border-t-2 border-dashed border-gray-300 my-4"></div>

Outline Utilities

Outlines (Focus States)
<!-- Outline width -->
<button class="outline-none">No outline</button>
<button class="outline outline-2">2px outline</button>
<button class="outline outline-4">4px outline</button>

<!-- Outline color -->
<button class="outline outline-blue-500">Blue outline</button>
<button class="outline outline-red-500">Red outline</button>

<!-- Outline style -->
<button class="outline outline-dashed">Dashed outline</button>
<button class="outline outline-dotted">Dotted outline</button>

<!-- Outline offset -->
<button class="outline outline-2 outline-offset-2 outline-blue-500">
    Outline with offset
</button>

<!-- Focus visible outline -->
<button class="focus:outline focus:outline-2 focus:outline-blue-500">
    Shows outline on focus
</button>

Divide Utilities

Dividers Between Children
<!-- Vertical dividers -->
<div class="divide-y divide-gray-300">
    <div class="py-2">Item 1</div>
    <div class="py-2">Item 2</div>
    <div class="py-2">Item 3</div>
</div>

<!-- Horizontal dividers -->
<div class="flex divide-x divide-gray-300">
    <div class="px-4">Column 1</div>
    <div class="px-4">Column 2</div>
    <div class="px-4">Column 3</div>
</div>

<!-- Colored dividers -->
<div class="divide-y-2 divide-blue-500">
    <div class="py-3">Section 1</div>
    <div class="py-3">Section 2</div>
</div>

<!-- Dashed dividers -->
<div class="divide-y divide-dashed divide-gray-400">
    <div class="py-2">Item 1</div>
    <div class="py-2">Item 2</div>
</div>

Practical Border Examples

Real-World Border Patterns
<!-- Card with border -->
<div class="border border-gray-200 rounded-lg p-6 hover:border-blue-500 transition">
    <h3 class="font-bold mb-2">Card Title</h3>
    <p class="text-gray-600">Card content...</p>
</div>

<!-- Card with accent border -->
<div class="border-l-4 border-blue-600 bg-blue-50 p-4 rounded-r">
    <h4 class="font-semibold text-blue-900">Info</h4>
    <p class="text-blue-700">Information message</p>
</div>

<!-- Button with border -->
<button class="border-2 border-blue-600 text-blue-600 px-6 py-2 rounded-lg hover:bg-blue-600 hover:text-white transition">
    Outline Button
</button>

<!-- Avatar with border -->
<img src="avatar.jpg" class="w-20 h-20 rounded-full border-4 border-white shadow-lg">

<!-- Navigation tabs -->
<div class="flex border-b border-gray-300">
    <button class="px-4 py-2 border-b-2 border-blue-600 text-blue-600">Active</button>
    <button class="px-4 py-2 border-b-2 border-transparent hover:border-gray-300">Tab 2</button>
    <button class="px-4 py-2 border-b-2 border-transparent hover:border-gray-300">Tab 3</button>
</div>

<!-- List with dividers -->
<ul class="divide-y divide-gray-200 border border-gray-200 rounded-lg">
    <li class="p-4 hover:bg-gray-50">List item 1</li>
    <li class="p-4 hover:bg-gray-50">List item 2</li>
    <li class="p-4 hover:bg-gray-50">List item 3</li>
</ul>

<!-- Badge with border -->
<span class="inline-block border-2 border-green-500 text-green-700 px-3 py-1 rounded-full text-sm font-medium">
    Active
</span>

<!-- Input with focus border -->
<input type="text" class="border-2 border-gray-300 rounded-lg px-4 py-2 focus:border-blue-500 focus:outline-none">
Practice Tasks
  • Create a card component with a subtle border (border-gray-200) that changes to blue on hover
  • Build an alert box with a thick left border accent (border-l-4) and rounded corners
  • Design a navigation tab system with bottom border indicators for the active tab
  • Create a list with dividers between items using the divide-y utility

Key Takeaways

  • border-{width}: Sets border width (0, 2, 4, 8) on all sides or specific sides (t, r, b, l)
  • border-{color}: Sets border color using Tailwind's color palette
  • rounded-{size}: Adds border radius from sm to 3xl, or use rounded-full for circles
  • border-{style}: Sets border style (solid, dashed, dotted, double, none)
  • divide-{x/y}: Adds borders between child elements automatically
  • outline: Controls outline appearance, useful for focus states

What's Next?

Next Topic: Continue to Tables to learn about styling tables with Tailwind CSS utilities.

Effects in Tailwind CSS

Add depth and visual interest with shadows, opacity, and blend modes

Understanding Effects

Effects utilities allow you to add visual depth and sophistication to your designs. Tailwind provides utilities for box shadows, drop shadows, opacity, and mixing blend modes that can create stunning visual effects.

Box Shadows

Shadow Sizes
<!-- Shadow scale from small to extra large -->
<div class="shadow-sm bg-white p-6 rounded">Small shadow</div>
<div class="shadow bg-white p-6 rounded">Default shadow</div>
<div class="shadow-md bg-white p-6 rounded">Medium shadow</div>
<div class="shadow-lg bg-white p-6 rounded">Large shadow</div>
<div class="shadow-xl bg-white p-6 rounded">Extra large shadow</div>
<div class="shadow-2xl bg-white p-6 rounded">2X large shadow</div>

<!-- No shadow -->
<div class="shadow-none bg-white p-6 rounded">No shadow</div>

<!-- Inner shadow -->
<div class="shadow-inner bg-white p-6 rounded">Inner shadow (inset)</div>
Shadow Colors
<!-- Colored shadows -->
<div class="shadow-lg shadow-blue-500/50 bg-white p-6 rounded">
    Blue shadow
</div>

<div class="shadow-lg shadow-red-500/50 bg-white p-6 rounded">
    Red shadow
</div>

<div class="shadow-lg shadow-green-500/50 bg-white p-6 rounded">
    Green shadow
</div>

<div class="shadow-lg shadow-purple-500/50 bg-white p-6 rounded">
    Purple shadow
</div>

<!-- Custom opacity -->
<div class="shadow-xl shadow-blue-500/75 bg-white p-6 rounded">
    75% opacity shadow
</div>
Interactive Shadows
<!-- Hover shadow increase -->
<div class="bg-white p-6 rounded shadow hover:shadow-xl transition-shadow cursor-pointer">
    Hover to increase shadow
</div>

<!-- Click shadow decrease -->
<button class="bg-blue-500 text-white px-6 py-2 rounded shadow-lg active:shadow-inner">
    Click for inset shadow
</button>

<!-- Card with growing shadow -->
<div class="bg-white rounded-lg p-6 shadow-md hover:shadow-2xl transform hover:-translate-y-1 transition-all duration-300">
    <h3 class="font-bold text-xl mb-2">Interactive Card</h3>
    <p class="text-gray-600">Shadow grows on hover</p>
</div>

Drop Shadow (Filter)

Drop Shadow Utilities
<!-- Drop shadow sizes -->
<div class="drop-shadow-sm">
    <img src="icon.png" class="w-24">
</div>

<div class="drop-shadow">
    <img src="icon.png" class="w-24">
</div>

<div class="drop-shadow-md">
    <img src="icon.png" class="w-24">
</div>

<div class="drop-shadow-lg">
    <img src="icon.png" class="w-24">
</div>

<div class="drop-shadow-xl">
    <img src="icon.png" class="w-24">
</div>

<div class="drop-shadow-2xl">
    <img src="icon.png" class="w-24">
</div>

<!-- No drop shadow -->
<div class="drop-shadow-none">
    <img src="icon.png" class="w-24">
</div>

<!-- Drop shadow on text/SVG -->
<svg class="w-24 h-24 text-blue-500 drop-shadow-lg" fill="currentColor" viewBox="0 0 20 20">
    <path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0z"></path>
</svg>

Opacity

Opacity Levels
<!-- Opacity scale -->
<div class="opacity-0 bg-blue-500 p-4">0% - Invisible</div>
<div class="opacity-25 bg-blue-500 p-4">25%</div>
<div class="opacity-50 bg-blue-500 p-4">50%</div>
<div class="opacity-75 bg-blue-500 p-4">75%</div>
<div class="opacity-100 bg-blue-500 p-4">100% - Opaque</div>

<!-- Hover opacity -->
<img src="image.jpg" class="opacity-75 hover:opacity-100 transition-opacity">

<!-- Disabled state with opacity -->
<button class="bg-blue-500 text-white px-6 py-2 rounded disabled:opacity-50" disabled>
    Disabled Button
</button>
Opacity with Overlays
<!-- Image overlay -->
<div class="relative">
    <img src="hero.jpg" class="w-full h-64 object-cover">
    <div class="absolute inset-0 bg-black opacity-50"></div>
    <div class="absolute inset-0 flex items-center justify-center">
        <h2 class="text-white text-4xl font-bold">Hero Title</h2>
    </div>
</div>

<!-- Hover reveal overlay -->
<div class="group relative overflow-hidden">
    <img src="image.jpg" class="w-full">
    <div class="absolute inset-0 bg-blue-600 opacity-0 group-hover:opacity-75 transition-opacity flex items-center justify-center">
        <button class="bg-white text-blue-600 px-6 py-2 rounded">View</button>
    </div>
</div>

Mix Blend Modes

Blend Mode Effects
<!-- Basic blend modes -->
<div class="bg-blue-500 p-8">
    <div class="mix-blend-multiply bg-red-500 p-4">Multiply</div>
</div>

<div class="bg-blue-500 p-8">
    <div class="mix-blend-screen bg-red-500 p-4">Screen</div>
</div>

<div class="bg-blue-500 p-8">
    <div class="mix-blend-overlay bg-red-500 p-4">Overlay</div>
</div>

<div class="bg-blue-500 p-8">
    <div class="mix-blend-darken bg-red-500 p-4">Darken</div>
</div>

<div class="bg-blue-500 p-8">
    <div class="mix-blend-lighten bg-red-500 p-4">Lighten</div>
</div>

<div class="bg-blue-500 p-8">
    <div class="mix-blend-difference bg-red-500 p-4">Difference</div>
</div>

<!-- Text over image -->
<div class="relative">
    <img src="colorful-bg.jpg" class="w-full h-64 object-cover">
    <h1 class="absolute inset-0 flex items-center justify-center text-6xl font-bold text-white mix-blend-difference">
        Blend Text
    </h1>
</div>

Background Blend Modes

Background Blending
<!-- Blend background image with color -->
<div class="bg-blue-500 bg-[url('pattern.jpg')] bg-blend-multiply h-64">
    Multiply blend
</div>

<div class="bg-red-500 bg-[url('pattern.jpg')] bg-blend-screen h-64">
    Screen blend
</div>

<div class="bg-green-500 bg-[url('pattern.jpg')] bg-blend-overlay h-64">
    Overlay blend
</div>

<div class="bg-purple-500 bg-[url('pattern.jpg')] bg-blend-darken h-64">
    Darken blend
</div>

<!-- Duotone effect -->
<div class="bg-gradient-to-br from-purple-600 to-blue-500 bg-[url('photo.jpg')] bg-blend-multiply bg-cover h-96">
    <div class="p-8 text-white">
        <h2 class="text-4xl font-bold">Duotone Effect</h2>
    </div>
</div>

Ring Effects

Focus Rings and Outlines
<!-- Ring sizes -->
<button class="ring-1 ring-blue-500 px-6 py-2 rounded">Ring 1</button>
<button class="ring-2 ring-blue-500 px-6 py-2 rounded">Ring 2</button>
<button class="ring-4 ring-blue-500 px-6 py-2 rounded">Ring 4</button>
<button class="ring-8 ring-blue-500 px-6 py-2 rounded">Ring 8</button>

<!-- Ring colors -->
<button class="ring-4 ring-red-500 px-6 py-2 rounded">Red Ring</button>
<button class="ring-4 ring-green-500 px-6 py-2 rounded">Green Ring</button>

<!-- Ring opacity -->
<button class="ring-4 ring-blue-500/50 px-6 py-2 rounded">50% Ring</button>

<!-- Ring offset -->
<button class="ring-4 ring-blue-500 ring-offset-2 px-6 py-2 rounded">With Offset</button>
<button class="ring-4 ring-blue-500 ring-offset-4 ring-offset-gray-100 px-6 py-2 rounded">Larger Offset</button>

<!-- Focus ring -->
<input type="text" class="border-2 border-gray-300 px-4 py-2 rounded focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">

Practical Effect Examples

Real-World Effect Patterns
<!-- Elevated card -->
<div class="bg-white rounded-lg shadow-xl p-6 hover:shadow-2xl transition-shadow">
    <h3 class="text-xl font-bold mb-2">Premium Card</h3>
    <p class="text-gray-600">With elevated shadow</p>
</div>

<!-- Glowing button -->
<button class="bg-blue-600 text-white px-8 py-3 rounded-lg shadow-lg shadow-blue-500/50 hover:shadow-blue-500/75 transition-shadow">
    Glow Button
</button>

<!-- Floating action button -->
<button class="fixed bottom-8 right-8 bg-blue-600 text-white p-4 rounded-full shadow-2xl hover:shadow-blue-500/50 transition-shadow">
    +
</button>

<!-- Image with subtle overlay -->
<div class="relative group overflow-hidden rounded-lg">
    <img src="product.jpg" class="w-full h-64 object-cover">
    <div class="absolute inset-0 bg-gradient-to-t from-black/75 to-transparent opacity-0 group-hover:opacity-100 transition-opacity">
        <div class="absolute bottom-0 p-6 text-white">
            <h3 class="text-xl font-bold">Product Name</h3>
            <p class="text-sm">$99.99</p>
        </div>
    </div>
</div>

<!-- Status indicator with glow -->
<div class="flex items-center space-x-2">
    <div class="w-3 h-3 bg-green-500 rounded-full shadow-lg shadow-green-500/50"></div>
    <span>Online</span>
</div>

<!-- Neumorphic button -->
<button class="bg-gray-200 text-gray-800 px-6 py-3 rounded-lg shadow-inner hover:shadow-none transition-shadow">
    Pressed Effect
</button>

<!-- Modal backdrop -->
<div class="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center">
    <div class="bg-white rounded-lg shadow-2xl p-8 max-w-md">
        <h2 class="text-2xl font-bold mb-4">Modal Title</h2>
        <p class="text-gray-600 mb-6">Modal content...</p>
        <button class="bg-blue-600 text-white px-6 py-2 rounded">Close</button>
    </div>
</div>

<!-- Pricing card with emphasis -->
<div class="bg-white rounded-lg shadow-md hover:shadow-2xl border-2 border-transparent hover:border-blue-500 transition-all p-8">
    <h3 class="text-2xl font-bold mb-4">Pro Plan</h3>
    <p class="text-4xl font-bold mb-6">$29<span class="text-lg font-normal text-gray-500">/mo</span></p>
    <button class="w-full bg-blue-600 text-white py-3 rounded-lg shadow-lg shadow-blue-500/30">
        Get Started
    </button>
</div>
Practice Tasks
  • Create a card that increases shadow from shadow-md to shadow-2xl on hover with smooth transition
  • Build a button with a glowing effect using colored shadow (shadow-blue-500/50) that intensifies on hover
  • Design an image gallery with opacity overlay that appears on hover (opacity-0 to opacity-75)
  • Create a form input with a focus ring effect (ring-2 ring-blue-500) when focused

Key Takeaways

  • shadow-{size}: Adds box shadow from sm to 2xl, plus shadow-inner for inset shadows
  • drop-shadow-{size}: Adds drop shadow filter to images, SVG, and text
  • opacity-{amount}: Controls opacity from 0 (transparent) to 100 (opaque)
  • mix-blend-{mode}: Sets how element content blends with background
  • ring-{width}: Adds outline rings, perfect for focus states
  • Colored shadows: Use shadow-{color}/{opacity} for colored shadow effects

What's Next?

Next Topic: Continue to Filters to learn about blur, brightness, contrast, and other filter effects in Tailwind CSS.

Filters in Tailwind CSS

Apply blur, brightness, contrast, and other filter effects

Understanding Filters

CSS filters allow you to apply graphical effects like blur, brightness adjustment, contrast, and more to elements. Tailwind provides utilities for all major filter properties, making it easy to create sophisticated visual effects.

Blur Filter

Blur Effects
<!-- Blur intensities -->
<img src="image.jpg" class="blur-none">
<img src="image.jpg" class="blur-sm">
<img src="image.jpg" class="blur">
<img src="image.jpg" class="blur-md">
<img src="image.jpg" class="blur-lg">
<img src="image.jpg" class="blur-xl">
<img src="image.jpg" class="blur-2xl">
<img src="image.jpg" class="blur-3xl">

<!-- Hover blur effect -->
<img src="image.jpg" class="hover:blur-sm transition">

<!-- Remove blur on hover -->
<img src="image.jpg" class="blur hover:blur-none transition">

Backdrop Blur

Background Blur (Glass Effect)
<!-- Backdrop blur for glass morphism -->
<div class="relative">
    <img src="background.jpg" class="w-full h-96 object-cover">
    <div class="absolute inset-0 flex items-center justify-center">
        <div class="bg-white/30 backdrop-blur-sm p-8 rounded-lg">
            Small backdrop blur
        </div>
    </div>
</div>

<!-- Different blur intensities -->
<div class="bg-white/30 backdrop-blur-sm p-6 rounded">Subtle blur</div>
<div class="bg-white/30 backdrop-blur p-6 rounded">Default blur</div>
<div class="bg-white/30 backdrop-blur-md p-6 rounded">Medium blur</div>
<div class="bg-white/30 backdrop-blur-lg p-6 rounded">Large blur</div>
<div class="bg-white/30 backdrop-blur-xl p-6 rounded">Extra large blur</div>

<!-- Glass card -->
<div class="bg-white/20 backdrop-blur-md border border-white/30 rounded-xl p-6 shadow-xl">
    <h3 class="text-xl font-bold mb-2">Glass Card</h3>
    <p>Beautiful frosted glass effect</p>
</div>

Brightness Filter

Brightness Adjustments
<!-- Brightness levels -->
<img src="image.jpg" class="brightness-0">    <!-- Completely black -->
<img src="image.jpg" class="brightness-50">   <!-- Half brightness -->
<img src="image.jpg" class="brightness-75">   <!-- 75% brightness -->
<img src="image.jpg" class="brightness-100">  <!-- Normal -->
<img src="image.jpg" class="brightness-125">  <!-- 25% brighter -->
<img src="image.jpg" class="brightness-150">  <!-- 50% brighter -->
<img src="image.jpg" class="brightness-200">  <!-- Double brightness -->

<!-- Hover brightness -->
<img src="image.jpg" class="brightness-75 hover:brightness-100 transition">

<!-- Lighten on hover -->
<img src="image.jpg" class="hover:brightness-110 transition cursor-pointer">

Contrast Filter

Contrast Adjustments
<!-- Contrast levels -->
<img src="image.jpg" class="contrast-0">     <!-- No contrast (gray) -->
<img src="image.jpg" class="contrast-50">    <!-- Low contrast -->
<img src="image.jpg" class="contrast-100">   <!-- Normal -->
<img src="image.jpg" class="contrast-125">   <!-- High contrast -->
<img src="image.jpg" class="contrast-150">   <!-- Higher contrast -->
<img src="image.jpg" class="contrast-200">   <!-- Maximum contrast -->

<!-- Enhance on hover -->
<img src="image.jpg" class="contrast-100 hover:contrast-125 transition">

Grayscale Filter

Grayscale Effects
<!-- Grayscale levels -->
<img src="image.jpg" class="grayscale-0">    <!-- Full color -->
<img src="image.jpg" class="grayscale">      <!-- Full grayscale -->

<!-- Partial grayscale with arbitrary value -->
<img src="image.jpg" class="grayscale-[0.5]"> <!-- 50% grayscale -->

<!-- Remove grayscale on hover -->
<img src="image.jpg" class="grayscale hover:grayscale-0 transition">

<!-- Gallery with grayscale effect -->
<div class="grid grid-cols-3 gap-4">
    <img src="img1.jpg" class="grayscale hover:grayscale-0 transition duration-300 cursor-pointer">
    <img src="img2.jpg" class="grayscale hover:grayscale-0 transition duration-300 cursor-pointer">
    <img src="img3.jpg" class="grayscale hover:grayscale-0 transition duration-300 cursor-pointer">
</div>

Hue Rotate Filter

Color Shifting
<!-- Hue rotation -->
<img src="image.jpg" class="hue-rotate-0">     <!-- No rotation -->
<img src="image.jpg" class="hue-rotate-15">    <!-- 15 degrees -->
<img src="image.jpg" class="hue-rotate-30">    <!-- 30 degrees -->
<img src="image.jpg" class="hue-rotate-60">    <!-- 60 degrees -->
<img src="image.jpg" class="hue-rotate-90">    <!-- 90 degrees -->
<img src="image.jpg" class="hue-rotate-180">   <!-- 180 degrees -->

<!-- Negative rotation -->
<img src="image.jpg" class="-hue-rotate-15">
<img src="image.jpg" class="-hue-rotate-30">

<!-- Animated hue shift -->
<img src="image.jpg" class="hover:hue-rotate-180 transition duration-500">

Invert Filter

Color Inversion
<!-- Invert colors -->
<img src="image.jpg" class="invert-0">       <!-- Normal -->
<img src="image.jpg" class="invert">         <!-- Fully inverted -->

<!-- Partial inversion -->
<img src="image.jpg" class="invert-[0.5]">   <!-- 50% inverted -->

<!-- Toggle invert on hover -->
<img src="image.jpg" class="hover:invert transition">

<!-- Dark mode logo swap -->
<img src="logo.png" class="dark:invert">

Saturate Filter

Saturation Control
<!-- Saturation levels -->
<img src="image.jpg" class="saturate-0">     <!-- Desaturated (grayscale) -->
<img src="image.jpg" class="saturate-50">    <!-- Low saturation -->
<img src="image.jpg" class="saturate-100">   <!-- Normal -->
<img src="image.jpg" class="saturate-150">   <!-- High saturation -->
<img src="image.jpg" class="saturate-200">   <!-- Very high saturation -->

<!-- Boost saturation on hover -->
<img src="image.jpg" class="saturate-100 hover:saturate-150 transition">

Sepia Filter

Vintage Sepia Tone
<!-- Sepia tones -->
<img src="image.jpg" class="sepia-0">        <!-- No sepia -->
<img src="image.jpg" class="sepia">          <!-- Full sepia -->

<!-- Partial sepia -->
<img src="image.jpg" class="sepia-[0.5]">    <!-- 50% sepia -->

<!-- Vintage photo effect -->
<img src="photo.jpg" class="sepia contrast-125 brightness-90">

<!-- Remove sepia on hover -->
<img src="image.jpg" class="sepia hover:sepia-0 transition">

Combined Filters

Multiple Filter Effects
<!-- Combine multiple filters -->
<img src="image.jpg" class="brightness-110 contrast-125 saturate-150">

<!-- Vintage effect -->
<img src="photo.jpg" class="sepia-[0.8] contrast-125 brightness-90">

<!-- High-key effect -->
<img src="image.jpg" class="brightness-125 contrast-75 saturate-75">

<!-- Dark mood -->
<img src="image.jpg" class="brightness-75 contrast-125 saturate-50">

<!-- Dramatic black and white -->
<img src="image.jpg" class="grayscale contrast-150 brightness-90">

<!-- Interactive filter changes -->
<img src="image.jpg" class="grayscale brightness-75 hover:grayscale-0 hover:brightness-100 transition duration-500">

Practical Filter Examples

Real-World Filter Patterns
<!-- Photo gallery with hover effects -->
<div class="grid grid-cols-3 gap-4">
    <div class="overflow-hidden rounded-lg">
        <img src="photo1.jpg" class="w-full grayscale hover:grayscale-0 hover:scale-110 transition duration-300 cursor-pointer">
    </div>
    <div class="overflow-hidden rounded-lg">
        <img src="photo2.jpg" class="w-full brightness-75 hover:brightness-100 hover:scale-110 transition duration-300 cursor-pointer">
    </div>
    <div class="overflow-hidden rounded-lg">
        <img src="photo3.jpg" class="w-full sepia hover:sepia-0 hover:scale-110 transition duration-300 cursor-pointer">
    </div>
</div>

<!-- Hero with backdrop blur -->
<div class="relative h-screen">
    <img src="hero-bg.jpg" class="absolute inset-0 w-full h-full object-cover">
    <div class="absolute inset-0 bg-black/40"></div>
    <div class="relative z-10 h-full flex items-center justify-center">
        <div class="bg-white/10 backdrop-blur-lg border border-white/20 rounded-2xl p-12 max-w-2xl">
            <h1 class="text-5xl font-bold text-white mb-4">Glass Morphism Hero</h1>
            <p class="text-xl text-white/90">Beautiful frosted glass effect</p>
        </div>
    </div>
</div>

<!-- Disabled/inactive state -->
<button class="px-6 py-2 bg-blue-500 text-white rounded disabled:grayscale disabled:brightness-75 disabled:cursor-not-allowed" disabled>
    Disabled Button
</button>

<!-- Loading overlay with blur -->
<div class="fixed inset-0 bg-white/80 backdrop-blur-sm flex items-center justify-center z-50">
    <div class="text-center">
        <div class="animate-spin h-12 w-12 border-4 border-blue-500 border-t-transparent rounded-full mx-auto mb-4"></div>
        <p class="text-lg font-medium">Loading...</p>
    </div>
</div>

<!-- Card with glass effect -->
<div class="relative overflow-hidden rounded-xl">
    <div class="absolute inset-0 bg-gradient-to-br from-blue-500 to-purple-600"></div>
    <div class="relative bg-white/10 backdrop-blur-md border border-white/20 p-8 m-4">
        <h3 class="text-2xl font-bold text-white mb-2">Glass Card</h3>
        <p class="text-white/80">Modern glassmorphism design</p>
    </div>
</div>

<!-- Thumbnail with filter preview -->
<div class="space-y-4">
    <div class="group cursor-pointer">
        <img src="image.jpg" class="w-full h-48 object-cover rounded-lg group-hover:brightness-110 transition">
        <p class="mt-2 text-center text-sm text-gray-600 group-hover:text-gray-900 transition">Original</p>
    </div>
</div>
Practice Tasks
  • Create a photo gallery where images are grayscale by default and reveal full color on hover
  • Build a glass morphism card using backdrop-blur-lg with semi-transparent background
  • Design a vintage photo effect combining sepia, contrast-125, and brightness-90 filters
  • Create a loading overlay with backdrop-blur-sm and semi-transparent white background

Key Takeaways

  • blur-{size}: Blurs element content from sm to 3xl
  • backdrop-blur-{size}: Blurs background behind element (glassmorphism effect)
  • brightness-{amount}: Adjusts brightness from 0 (black) to 200 (double brightness)
  • contrast-{amount}: Controls contrast from 0 (gray) to 200 (maximum contrast)
  • grayscale: Removes color (combine with hover:grayscale-0 for effects)
  • Multiple filters: Combine filters for sophisticated effects like vintage photos

What's Next?

Next Topic: Continue to Dark Mode to learn how to implement dark mode in your Tailwind CSS projects.

Tables in Tailwind CSS

Style beautiful and responsive tables with utility classes

Understanding Table Utilities

While Tailwind doesn't have dedicated table components, you can create beautifully styled tables using layout, spacing, border, and color utilities. This approach gives you complete control over table appearance.

Table Layout

Basic Table Structure
<!-- Auto layout (default) -->
<table class="table-auto w-full">
    <thead>
        <tr>
            <th>Name</th>
            <th>Email</th>
            <th>Role</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>John Doe</td>
            <td>john@example.com</td>
            <td>Admin</td>
        </tr>
    </tbody>
</table>

<!-- Fixed layout -->
<table class="table-fixed w-full">
    <thead>
        <tr>
            <th class="w-1/3">Name</th>
            <th class="w-1/3">Email</th>
            <th class="w-1/3">Role</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>John Doe</td>
            <td>john@example.com</td>
            <td>Admin</td>
        </tr>
    </tbody>
</table>

Styled Table with Borders

Table with Borders
<table class="min-w-full border-collapse border border-gray-300">
    <thead class="bg-gray-100">
        <tr>
            <th class="border border-gray-300 px-4 py-2 text-left">Name</th>
            <th class="border border-gray-300 px-4 py-2 text-left">Email</th>
            <th class="border border-gray-300 px-4 py-2 text-left">Role</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td class="border border-gray-300 px-4 py-2">John Doe</td>
            <td class="border border-gray-300 px-4 py-2">john@example.com</td>
            <td class="border border-gray-300 px-4 py-2">Admin</td>
        </tr>
        <tr>
            <td class="border border-gray-300 px-4 py-2">Jane Smith</td>
            <td class="border border-gray-300 px-4 py-2">jane@example.com</td>
            <td class="border border-gray-300 px-4 py-2">User</td>
        </tr>
    </tbody>
</table>

Striped Table

Alternating Row Colors
<table class="min-w-full">
    <thead class="bg-gray-800 text-white">
        <tr>
            <th class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
                Name
            </th>
            <th class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
                Email
            </th>
            <th class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
                Status
            </th>
        </tr>
    </thead>
    <tbody class="bg-white divide-y divide-gray-200">
        <tr class="even:bg-gray-50">
            <td class="px-6 py-4 whitespace-nowrap">John Doe</td>
            <td class="px-6 py-4 whitespace-nowrap">john@example.com</td>
            <td class="px-6 py-4 whitespace-nowrap">
                <span class="px-2 py-1 text-xs font-medium rounded-full bg-green-100 text-green-800">
                    Active
                </span>
            </td>
        </tr>
        <tr class="even:bg-gray-50">
            <td class="px-6 py-4 whitespace-nowrap">Jane Smith</td>
            <td class="px-6 py-4 whitespace-nowrap">jane@example.com</td>
            <td class="px-6 py-4 whitespace-nowrap">
                <span class="px-2 py-1 text-xs font-medium rounded-full bg-green-100 text-green-800">
                    Active
                </span>
            </td>
        </tr>
    </tbody>
</table>

Hoverable Rows

Interactive Table Rows
<table class="min-w-full">
    <thead class="bg-gray-50">
        <tr>
            <th class="px-6 py-3 text-left text-sm font-medium text-gray-700">Product</th>
            <th class="px-6 py-3 text-left text-sm font-medium text-gray-700">Price</th>
            <th class="px-6 py-3 text-left text-sm font-medium text-gray-700">Stock</th>
        </tr>
    </thead>
    <tbody class="bg-white divide-y divide-gray-200">
        <tr class="hover:bg-gray-50 transition-colors cursor-pointer">
            <td class="px-6 py-4">Product A</td>
            <td class="px-6 py-4">$29.99</td>
            <td class="px-6 py-4">In Stock</td>
        </tr>
        <tr class="hover:bg-gray-50 transition-colors cursor-pointer">
            <td class="px-6 py-4">Product B</td>
            <td class="px-6 py-4">$49.99</td>
            <td class="px-6 py-4">Low Stock</td>
        </tr>
        <tr class="hover:bg-gray-50 transition-colors cursor-pointer">
            <td class="px-6 py-4">Product C</td>
            <td class="px-6 py-4">$19.99</td>
            <td class="px-6 py-4">Out of Stock</td>
        </tr>
    </tbody>
</table>

Responsive Tables

Scrollable Tables
<!-- Horizontal scroll on small screens -->
<div class="overflow-x-auto">
    <table class="min-w-full">
        <thead class="bg-gray-100">
            <tr>
                <th class="px-6 py-3 text-left">ID</th>
                <th class="px-6 py-3 text-left">Name</th>
                <th class="px-6 py-3 text-left">Email</th>
                <th class="px-6 py-3 text-left">Role</th>
                <th class="px-6 py-3 text-left">Department</th>
                <th class="px-6 py-3 text-left">Status</th>
            </tr>
        </thead>
        <tbody class="bg-white">
            <tr>
                <td class="px-6 py-4">001</td>
                <td class="px-6 py-4 whitespace-nowrap">John Doe</td>
                <td class="px-6 py-4 whitespace-nowrap">john@example.com</td>
                <td class="px-6 py-4">Admin</td>
                <td class="px-6 py-4">IT</td>
                <td class="px-6 py-4">Active</td>
            </tr>
        </tbody>
    </table>
</div>

<!-- Responsive with shadow scroll indicator -->
<div class="overflow-x-auto shadow-md rounded-lg">
    <table class="min-w-full">
        <!-- Table content -->
    </table>
</div>

Table with Actions

Action Buttons in Table
<table class="min-w-full">
    <thead class="bg-gray-50">
        <tr>
            <th class="px-6 py-3 text-left text-sm font-medium text-gray-700">Name</th>
            <th class="px-6 py-3 text-left text-sm font-medium text-gray-700">Email</th>
            <th class="px-6 py-3 text-left text-sm font-medium text-gray-700">Status</th>
            <th class="px-6 py-3 text-right text-sm font-medium text-gray-700">Actions</th>
        </tr>
    </thead>
    <tbody class="bg-white divide-y divide-gray-200">
        <tr>
            <td class="px-6 py-4">John Doe</td>
            <td class="px-6 py-4">john@example.com</td>
            <td class="px-6 py-4">
                <span class="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">
                    Active
                </span>
            </td>
            <td class="px-6 py-4 text-right space-x-2">
                <button class="text-blue-600 hover:text-blue-800">Edit</button>
                <button class="text-red-600 hover:text-red-800">Delete</button>
            </td>
        </tr>
    </tbody>
</table>

Compact Table

Dense Table Layout
<table class="min-w-full text-sm">
    <thead class="bg-gray-100">
        <tr>
            <th class="px-3 py-2 text-left font-medium text-gray-700">ID</th>
            <th class="px-3 py-2 text-left font-medium text-gray-700">Name</th>
            <th class="px-3 py-2 text-left font-medium text-gray-700">Status</th>
        </tr>
    </thead>
    <tbody class="bg-white">
        <tr class="border-b border-gray-200">
            <td class="px-3 py-2">001</td>
            <td class="px-3 py-2">John Doe</td>
            <td class="px-3 py-2">Active</td>
        </tr>
        <tr class="border-b border-gray-200">
            <td class="px-3 py-2">002</td>
            <td class="px-3 py-2">Jane Smith</td>
            <td class="px-3 py-2">Active</td>
        </tr>
    </tbody>
</table>

Practical Table Examples

Complete Table Patterns
<!-- Modern data table -->
<div class="overflow-hidden shadow ring-1 ring-black ring-opacity-5 rounded-lg">
    <table class="min-w-full divide-y divide-gray-300">
        <thead class="bg-gray-50">
            <tr>
                <th scope="col" class="py-3.5 pl-6 pr-3 text-left text-sm font-semibold text-gray-900">
                    Name
                </th>
                <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
                    Title
                </th>
                <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
                    Email
                </th>
                <th scope="col" class="relative py-3.5 pl-3 pr-6">
                    <span class="sr-only">Edit</span>
                </th>
            </tr>
        </thead>
        <tbody class="divide-y divide-gray-200 bg-white">
            <tr>
                <td class="whitespace-nowrap py-4 pl-6 pr-3 text-sm font-medium text-gray-900">
                    John Doe
                </td>
                <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
                    Software Engineer
                </td>
                <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
                    john@example.com
                </td>
                <td class="relative whitespace-nowrap py-4 pl-3 pr-6 text-right text-sm">
                    <a href="#" class="text-blue-600 hover:text-blue-900">Edit</a>
                </td>
            </tr>
        </tbody>
    </table>
</div>

<!-- Pricing table -->
<div class="overflow-x-auto">
    <table class="min-w-full">
        <thead>
            <tr class="border-b-2 border-gray-300">
                <th class="px-6 py-4 text-left">Feature</th>
                <th class="px-6 py-4 text-center bg-blue-50">Basic</th>
                <th class="px-6 py-4 text-center bg-purple-50">Pro</th>
                <th class="px-6 py-4 text-center bg-green-50">Enterprise</th>
            </tr>
        </thead>
        <tbody class="divide-y divide-gray-200">
            <tr>
                <td class="px-6 py-4">Users</td>
                <td class="px-6 py-4 text-center">5</td>
                <td class="px-6 py-4 text-center">20</td>
                <td class="px-6 py-4 text-center">Unlimited</td>
            </tr>
            <tr>
                <td class="px-6 py-4">Storage</td>
                <td class="px-6 py-4 text-center">10GB</td>
                <td class="px-6 py-4 text-center">100GB</td>
                <td class="px-6 py-4 text-center">1TB</td>
            </tr>
        </tbody>
    </table>
</div>
Practice Tasks
  • Create a striped table using even:bg-gray-50 on table rows with alternating colors
  • Build an interactive table with hover effects on rows (hover:bg-gray-50) and clickable action buttons
  • Design a responsive table wrapped in overflow-x-auto for horizontal scrolling on mobile devices
  • Create a data table with status badges (colored pills) and properly aligned action buttons in the last column

Key Takeaways

  • table-auto/table-fixed: Controls table layout algorithm (auto adjusts to content, fixed uses defined widths)
  • divide-y: Adds borders between table rows automatically
  • even:bg-{color}: Creates striped tables by styling even rows differently
  • overflow-x-auto: Makes tables horizontally scrollable on small screens
  • whitespace-nowrap: Prevents text wrapping in table cells
  • hover:bg-{color}: Adds interactive hover effects to table rows

What's Next?

Next Topic: Continue to Hover & Focus States to learn about interactive states and pseudo-classes in Tailwind CSS.

Transitions & Animations in Tailwind CSS

Add smooth transitions and animations to create dynamic interfaces

Understanding Transitions

Transitions allow you to create smooth animations when element properties change. Tailwind provides utilities for controlling transition properties, duration, timing functions, and delays.

Basic Transitions

Transition Properties
<!-- Transition all properties -->
<button class="bg-blue-500 hover:bg-blue-700 transition-all px-6 py-2 rounded text-white">
    Transition All
</button>

<!-- Transition specific properties -->
<button class="bg-blue-500 hover:bg-blue-700 transition-colors px-6 py-2 rounded text-white">
    Colors Only
</button>

<button class="bg-blue-500 hover:scale-110 transition-transform px-6 py-2 rounded text-white">
    Transform Only
</button>

<button class="shadow hover:shadow-2xl transition-shadow px-6 py-2 rounded bg-white">
    Shadow Only
</button>

<button class="opacity-50 hover:opacity-100 transition-opacity px-6 py-2 rounded bg-blue-500 text-white">
    Opacity Only
</button>

<!-- Transition shorthand -->
<button class="bg-blue-500 hover:bg-blue-700 transition px-6 py-2 rounded text-white">
    Default Transition
</button>

Transition Duration

Controlling Speed
<!-- Fast transition (75ms) -->
<button class="bg-blue-500 hover:bg-blue-700 transition duration-75 px-6 py-2 rounded text-white">
    Very Fast
</button>

<!-- Default (150ms) -->
<button class="bg-blue-500 hover:bg-blue-700 transition duration-150 px-6 py-2 rounded text-white">
    Fast
</button>

<!-- Medium (300ms) -->
<button class="bg-blue-500 hover:bg-blue-700 transition duration-300 px-6 py-2 rounded text-white">
    Medium
</button>

<!-- Slow (500ms) -->
<button class="bg-blue-500 hover:bg-blue-700 transition duration-500 px-6 py-2 rounded text-white">
    Slow
</button>

<!-- Very slow (1000ms) -->
<button class="bg-blue-500 hover:bg-blue-700 transition duration-1000 px-6 py-2 rounded text-white">
    Very Slow
</button>

Transition Timing Functions

Easing Functions
<!-- Linear -->
<button class="bg-blue-500 hover:scale-110 transition duration-300 ease-linear px-6 py-2 rounded text-white">
    Linear
</button>

<!-- Ease in -->
<button class="bg-blue-500 hover:scale-110 transition duration-300 ease-in px-6 py-2 rounded text-white">
    Ease In
</button>

<!-- Ease out -->
<button class="bg-blue-500 hover:scale-110 transition duration-300 ease-out px-6 py-2 rounded text-white">
    Ease Out
</button>

<!-- Ease in-out (default) -->
<button class="bg-blue-500 hover:scale-110 transition duration-300 ease-in-out px-6 py-2 rounded text-white">
    Ease In-Out
</button>

Transition Delays

Delayed Transitions
<!-- No delay -->
<button class="bg-blue-500 hover:bg-blue-700 transition duration-300 px-6 py-2 rounded text-white">
    No Delay
</button>

<!-- 75ms delay -->
<button class="bg-blue-500 hover:bg-blue-700 transition duration-300 delay-75 px-6 py-2 rounded text-white">
    75ms Delay
</button>

<!-- 150ms delay -->
<button class="bg-blue-500 hover:bg-blue-700 transition duration-300 delay-150 px-6 py-2 rounded text-white">
    150ms Delay
</button>

<!-- 300ms delay -->
<button class="bg-blue-500 hover:bg-blue-700 transition duration-300 delay-300 px-6 py-2 rounded text-white">
    300ms Delay
</button>

<!-- Staggered animations -->
<div class="space-y-2">
    <div class="bg-blue-500 hover:translate-x-4 transition duration-300 delay-0 p-4 text-white">Item 1</div>
    <div class="bg-blue-500 hover:translate-x-4 transition duration-300 delay-75 p-4 text-white">Item 2</div>
    <div class="bg-blue-500 hover:translate-x-4 transition duration-300 delay-150 p-4 text-white">Item 3</div>
</div>

Keyframe Animations

Built-in Animations
<!-- Spin animation -->
<div class="animate-spin h-12 w-12 border-4 border-blue-500 border-t-transparent rounded-full"></div>

<!-- Ping animation -->
<div class="relative">
    <div class="animate-ping absolute h-12 w-12 rounded-full bg-blue-400 opacity-75"></div>
    <div class="relative h-12 w-12 rounded-full bg-blue-500"></div>
</div>

<!-- Pulse animation -->
<div class="animate-pulse bg-blue-500 h-12 w-12 rounded"></div>

<!-- Bounce animation -->
<div class="animate-bounce bg-blue-500 h-12 w-12 rounded"></div>

<!-- Loading spinner -->
<div class="flex items-center space-x-2">
    <div class="animate-spin h-5 w-5 border-2 border-blue-500 border-t-transparent rounded-full"></div>
    <span>Loading...</span>
</div>

Animation Control

Animation Play State
<!-- Pause animation on hover -->
<div class="animate-spin hover:animate-none h-12 w-12 border-4 border-blue-500 border-t-transparent rounded-full">
</div>

<!-- Animate on hover -->
<div class="hover:animate-spin h-12 w-12 border-4 border-blue-500 border-t-transparent rounded-full">
</div>

<!-- Pulse on hover -->
<button class="bg-blue-500 hover:animate-pulse text-white px-6 py-2 rounded">
    Hover to Pulse
</button>

Complex Transition Combinations

Multiple Properties
<!-- Card with multiple transitions -->
<div class="bg-white rounded-lg shadow hover:shadow-2xl
            transform hover:-translate-y-2
            transition-all duration-300
            p-6 cursor-pointer">
    <h3 class="text-xl font-bold mb-2">Hover Me</h3>
    <p class="text-gray-600">Multiple transitions applied</p>
</div>

<!-- Button with scale and color -->
<button class="bg-blue-500 hover:bg-blue-600
               text-white px-8 py-3 rounded-lg
               transform hover:scale-105 active:scale-95
               transition-all duration-200
               shadow-lg hover:shadow-xl">
    Interactive Button
</button>

<!-- Image with overlay transition -->
<div class="relative overflow-hidden rounded-lg group">
    <img src="image.jpg" class="transform group-hover:scale-110 transition-transform duration-500">
    <div class="absolute inset-0 bg-gradient-to-t from-black to-transparent
                opacity-0 group-hover:opacity-100
                transition-opacity duration-300">
        <div class="absolute bottom-0 left-0 right-0 p-6
                    transform translate-y-full group-hover:translate-y-0
                    transition-transform duration-300">
            <h3 class="text-white text-2xl font-bold">Image Title</h3>
        </div>
    </div>
</div>

Practical Animation Examples

Real-World Patterns
<!-- Loading button -->
<button class="bg-blue-500 text-white px-6 py-2 rounded inline-flex items-center" disabled>
    <div class="animate-spin mr-2 h-4 w-4 border-2 border-white border-t-transparent rounded-full"></div>
    Processing...
</button>

<!-- Notification badge with pulse -->
<div class="relative inline-block">
    <button class="bg-gray-800 text-white px-4 py-2 rounded">
        Notifications
    </button>
    <span class="absolute -top-1 -right-1 flex h-3 w-3">
        <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75"></span>
        <span class="relative inline-flex rounded-full h-3 w-3 bg-red-500"></span>
    </span>
</div>

<!-- Skeleton loader -->
<div class="space-y-4">
    <div class="h-4 bg-gray-200 rounded animate-pulse"></div>
    <div class="h-4 bg-gray-200 rounded animate-pulse w-5/6"></div>
    <div class="h-4 bg-gray-200 rounded animate-pulse w-4/6"></div>
</div>

<!-- Slide-in menu -->
<div class="fixed right-0 top-0 h-full w-64 bg-white shadow-lg
            transform translate-x-full hover:translate-x-0
            transition-transform duration-300">
    <div class="p-6">
        <h3 class="font-bold mb-4">Menu</h3>
        <ul class="space-y-2">
            <li><a href="#" class="block hover:text-blue-600 transition-colors">Link 1</a></li>
            <li><a href="#" class="block hover:text-blue-600 transition-colors">Link 2</a></li>
        </ul>
    </div>
</div>

<!-- Progress indicator -->
<div class="relative h-2 bg-gray-200 rounded-full overflow-hidden">
    <div class="absolute h-full bg-blue-500 rounded-full transition-all duration-500" style="width: 60%;"></div>
</div>

<!-- Floating action button -->
<button class="fixed bottom-8 right-8 bg-blue-600 text-white p-4 rounded-full shadow-lg
               hover:shadow-2xl hover:scale-110
               transform transition-all duration-200">
    <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path>
    </svg>
</button>
Practice Tasks
  • Create a button that smoothly transitions background color, scales up on hover, and scales down on active
  • Build a card that lifts up with shadow increase on hover using transform and transition utilities
  • Design a loading spinner using the animate-spin utility with a custom border style
  • Create an image gallery where images scale and show an overlay with staggered animations on hover

Key Takeaways

  • transition-{properties}: Defines which properties to animate (all, colors, opacity, shadow, transform)
  • duration-{time}: Controls animation speed (75, 150, 300, 500, 700, 1000ms)
  • ease-{function}: Sets timing function (linear, in, out, in-out)
  • delay-{time}: Adds delay before transition starts
  • animate-{name}: Applies built-in animations (spin, ping, pulse, bounce)
  • Combine with hover/focus: Use state variants to trigger transitions

What's Next?

Next Topic: Continue to Transforms to learn about scale, rotate, translate, and skew utilities.

Transforms in Tailwind CSS

Scale, rotate, translate, and skew elements with transform utilities

Understanding Transforms

CSS transforms allow you to modify the coordinate space of elements. Tailwind provides utilities for scaling, rotating, translating (moving), and skewing elements. These are perfect for creating interactive effects and animations.

Scale Transforms

Scaling Elements
<!-- Scale uniformly -->
<div class="scale-50 bg-blue-500 w-20 h-20">50%</div>
<div class="scale-75 bg-blue-500 w-20 h-20">75%</div>
<div class="scale-100 bg-blue-500 w-20 h-20">100%</div>
<div class="scale-125 bg-blue-500 w-20 h-20">125%</div>
<div class="scale-150 bg-blue-500 w-20 h-20">150%</div>

<!-- Scale on hover -->
<button class="bg-blue-500 text-white px-6 py-2 rounded
               hover:scale-110 transform transition">
    Hover to Scale
</button>

<!-- Scale X axis only -->
<div class="scale-x-150 bg-green-500 w-20 h-20">Wide</div>

<!-- Scale Y axis only -->
<div class="scale-y-150 bg-green-500 w-20 h-20">Tall</div>

Rotate Transforms

Rotating Elements
<!-- Rotate clockwise -->
<div class="rotate-0 bg-blue-500 w-20 h-20">0°</div>
<div class="rotate-45 bg-blue-500 w-20 h-20">45°</div>
<div class="rotate-90 bg-blue-500 w-20 h-20">90°</div>
<div class="rotate-180 bg-blue-500 w-20 h-20">180°</div>

<!-- Rotate counter-clockwise -->
<div class="-rotate-45 bg-red-500 w-20 h-20">-45°</div>
<div class="-rotate-90 bg-red-500 w-20 h-20">-90°</div>

<!-- Rotate on hover -->
<button class="bg-blue-500 text-white p-4 rounded-full
               hover:rotate-180 transform transition duration-500">
    ⟳
</button>

<!-- Spinning icon -->
<div class="hover:rotate-90 transition duration-300 inline-block">
    ⚙️
</div>

Translate Transforms

Moving Elements
<!-- Translate X axis -->
<div class="translate-x-4 bg-blue-500 w-20 h-20">Right 1rem</div>
<div class="translate-x-8 bg-blue-500 w-20 h-20">Right 2rem</div>
<div class="-translate-x-4 bg-blue-500 w-20 h-20">Left 1rem</div>

<!-- Translate Y axis -->
<div class="translate-y-4 bg-green-500 w-20 h-20">Down 1rem</div>
<div class="translate-y-8 bg-green-500 w-20 h-20">Down 2rem</div>
<div class="-translate-y-4 bg-green-500 w-20 h-20">Up 1rem</div>

<!-- Translate both axes -->
<div class="translate-x-4 translate-y-4 bg-purple-500 w-20 h-20">Diagonal</div>

<!-- Hover lift effect -->
<div class="bg-white shadow rounded-lg p-6
            hover:-translate-y-2 transform transition">
    Lifts on hover
</div>

<!-- Centering with translate -->
<div class="relative h-64 bg-gray-200">
    <div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2
                bg-blue-500 text-white p-4 rounded">
        Perfectly Centered
    </div>
</div>

Skew Transforms

Skewing Elements
<!-- Skew X axis -->
<div class="skew-x-0 bg-blue-500 w-20 h-20">0°</div>
<div class="skew-x-6 bg-blue-500 w-20 h-20">6°</div>
<div class="skew-x-12 bg-blue-500 w-20 h-20">12°</div>

<!-- Skew Y axis -->
<div class="skew-y-0 bg-green-500 w-20 h-20">0°</div>
<div class="skew-y-6 bg-green-500 w-20 h-20">6°</div>
<div class="skew-y-12 bg-green-500 w-20 h-20">12°</div>

<!-- Negative skew -->
<div class="-skew-x-12 bg-purple-500 w-20 h-20">-12°</div>

<!-- Skew on hover -->
<div class="bg-blue-500 w-20 h-20 hover:skew-y-6 transform transition">
    Hover me
</div>

Transform Origin

Controlling Transform Origin
<!-- Corner origins -->
<div class="origin-top-left rotate-45 bg-blue-500 w-20 h-20">Top Left</div>
<div class="origin-top rotate-45 bg-blue-500 w-20 h-20">Top</div>
<div class="origin-top-right rotate-45 bg-blue-500 w-20 h-20">Top Right</div>
<div class="origin-left rotate-45 bg-blue-500 w-20 h-20">Left</div>
<div class="origin-center rotate-45 bg-blue-500 w-20 h-20">Center</div>
<div class="origin-right rotate-45 bg-blue-500 w-20 h-20">Right</div>
<div class="origin-bottom-left rotate-45 bg-blue-500 w-20 h-20">Bottom Left</div>
<div class="origin-bottom rotate-45 bg-blue-500 w-20 h-20">Bottom</div>
<div class="origin-bottom-right rotate-45 bg-blue-500 w-20 h-20">Bottom Right</div>

<!-- Rotating from bottom for doors/flaps -->
<div class="origin-bottom hover:rotate-90 transform transition duration-500 bg-green-500 w-20 h-32">
    Door Effect
</div>

Combined Transforms

Multiple Transform Properties
<!-- Scale and rotate -->
<div class="scale-110 rotate-12 bg-blue-500 w-20 h-20">
    Scaled + Rotated
</div>

<!-- All transforms combined -->
<div class="scale-110 rotate-12 translate-x-4 translate-y-4 skew-x-6
            bg-purple-500 w-20 h-20">
    All Combined
</div>

<!-- Interactive card -->
<div class="bg-white rounded-lg shadow p-6
            hover:scale-105 hover:-rotate-1 hover:-translate-y-1
            transform transition-all duration-300 cursor-pointer">
    <h3 class="font-bold">Interactive Card</h3>
    <p>Hover for combined transforms</p>
</div>

3D Transforms (Perspective)

Perspective Effects
<!-- Rotate X (3D) -->
<div class="perspective-1000">
    <div class="rotate-x-12 bg-blue-500 w-32 h-32">Rotate X</div>
</div>

<!-- Rotate Y (3D) -->
<div class="perspective-1000">
    <div class="rotate-y-12 bg-green-500 w-32 h-32">Rotate Y</div>
</div>

<!-- Card flip effect -->
<div class="group perspective-1000 w-64 h-40 cursor-pointer">
    <div class="relative w-full h-full transition-transform duration-500
                transform-style-3d group-hover:rotate-y-180">
        <div class="absolute inset-0 bg-blue-500 text-white flex items-center justify-center rounded-lg backface-hidden">
            Front
        </div>
        <div class="absolute inset-0 bg-green-500 text-white flex items-center justify-center rounded-lg backface-hidden rotate-y-180">
            Back
        </div>
    </div>
</div>

Practical Transform Examples

Real-World Transform Patterns
<!-- Zoom on hover (images) -->
<div class="overflow-hidden rounded-lg">
    <img src="image.jpg" class="hover:scale-110 transform transition duration-500">
</div>

<!-- Button press effect -->
<button class="bg-blue-500 text-white px-6 py-2 rounded-lg
               hover:scale-105 active:scale-95
               transform transition">
    Press Me
</button>

<!-- Floating card -->
<div class="bg-white rounded-lg shadow-lg p-6
            hover:-translate-y-2 hover:shadow-2xl
            transform transition-all duration-300">
    <h3 class="text-xl font-bold mb-2">Floating Card</h3>
    <p class="text-gray-600">Lifts on hover</p>
</div>

<!-- Rotating loader -->
<div class="animate-spin h-12 w-12 border-4 border-blue-500 border-t-transparent rounded-full">
</div>

<!-- Icon button with rotate -->
<button class="bg-blue-500 text-white p-3 rounded-full
               hover:rotate-90 transform transition duration-300">
    ➕
</button>

<!-- Notification badge -->
<div class="relative inline-block">
    <button class="bg-gray-800 text-white px-4 py-2 rounded">
        Messages
    </button>
    <span class="absolute -top-2 -right-2 bg-red-500 text-white text-xs
                 w-6 h-6 flex items-center justify-center rounded-full
                 transform scale-0 group-hover:scale-100 transition">
        5
    </span>
</div>

<!-- Parallax layers -->
<div class="relative h-96 overflow-hidden">
    <div class="absolute inset-0 bg-blue-500 translate-y-0 hover:translate-y-4 transition-transform duration-1000">
        Layer 1
    </div>
    <div class="absolute inset-0 bg-blue-400 translate-y-0 hover:translate-y-8 transition-transform duration-1000">
        Layer 2
    </div>
</div>

<!-- Reveal content on hover -->
<div class="group relative overflow-hidden bg-gray-900 rounded-lg h-64">
    <img src="image.jpg" class="w-full h-full object-cover">
    <div class="absolute inset-0 bg-black/75
                transform translate-y-full group-hover:translate-y-0
                transition-transform duration-300
                flex items-center justify-center p-6">
        <div class="text-white text-center">
            <h3 class="text-2xl font-bold mb-2">Title</h3>
            <p>Hidden content revealed on hover</p>
        </div>
    </div>
</div>
Practice Tasks
  • Create a card that scales up (scale-105) and lifts (-translate-y-2) on hover with smooth transitions
  • Build a button with a press effect using scale-95 on active state
  • Design an image gallery where images zoom in (scale-110) when hovered, contained within overflow-hidden
  • Create a rotating icon button that spins 90 degrees on hover with transform origin at center

Key Takeaways

  • scale-{amount}: Scales element uniformly or on specific axis (scale-x-, scale-y-)
  • rotate-{degrees}: Rotates element clockwise or counter-clockwise (use negative values)
  • translate-{x/y}-{amount}: Moves element horizontally or vertically
  • skew-{x/y}-{degrees}: Skews element along X or Y axis
  • origin-{position}: Sets the transform origin point
  • Combine with transition: Add smooth animations to transforms

What's Next?

Next Topic: Continue to Effects to learn about shadows, opacity, and blend modes in Tailwind CSS.

Flexbox Utilities in Tailwind CSS

Create flexible, responsive layouts with flexbox

Flex Container

Use flex to create a flex container and inline-flex for inline flex containers.

Basic Flex Container
<!-- Flex container -->
<div class="flex">
    <div>Item 1</div>
    <div>Item 2</div>
    <div>Item 3</div>
</div>

<!-- Inline flex -->
<div class="inline-flex">
    <div>Inline Item 1</div>
    <div>Inline Item 2</div>
</div>

Flex Direction

Control Flow Direction
<!-- Row (default) -->
<div class="flex flex-row">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>

<!-- Row reverse -->
<div class="flex flex-row-reverse">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>

<!-- Column -->
<div class="flex flex-col">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>

<!-- Column reverse -->
<div class="flex flex-col-reverse">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>

<!-- Responsive direction -->
<div class="flex flex-col md:flex-row">
    <!-- Column on mobile, row on desktop -->
</div>

Justify Content

Horizontal Alignment
<!-- Start (default) -->
<div class="flex justify-start">
    <div>Item</div>
</div>

<!-- Center -->
<div class="flex justify-center">
    <div>Centered</div>
</div>

<!-- End -->
<div class="flex justify-end">
    <div>Item</div>
</div>

<!-- Space between -->
<div class="flex justify-between">
    <div>Left</div>
    <div>Right</div>
</div>

<!-- Space around -->
<div class="flex justify-around">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>

<!-- Space evenly -->
<div class="flex justify-evenly">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>

Align Items

Vertical Alignment
<!-- Stretch (default) -->
<div class="flex items-stretch h-32">
    <div>Stretched</div>
</div>

<!-- Start -->
<div class="flex items-start h-32">
    <div>Top</div>
</div>

<!-- Center -->
<div class="flex items-center h-32">
    <div>Middle</div>
</div>

<!-- End -->
<div class="flex items-end h-32">
    <div>Bottom</div>
</div>

<!-- Baseline -->
<div class="flex items-baseline">
    <div class="text-4xl">Large</div>
    <div class="text-base">Small</div>
</div>

<!-- Perfect centering -->
<div class="flex items-center justify-center h-screen">
    <div>Perfectly centered</div>
</div>

Flex Wrap

Control Wrapping
<!-- No wrap (default) -->
<div class="flex flex-nowrap">
    <div class="w-1/3">1</div>
    <div class="w-1/3">2</div>
    <div class="w-1/3">3</div>
    <div class="w-1/3">4</div> <!-- Overflows -->
</div>

<!-- Wrap -->
<div class="flex flex-wrap">
    <div class="w-1/3">1</div>
    <div class="w-1/3">2</div>
    <div class="w-1/3">3</div>
    <div class="w-1/3">4</div> <!-- Wraps to new line -->
</div>

<!-- Wrap reverse -->
<div class="flex flex-wrap-reverse">
    <!-- Wraps in reverse order -->
</div>

Align Content

Multi-Line Alignment
<!-- For wrapped flex containers -->
<div class="flex flex-wrap content-start h-64">
    <!-- Multiple items -->
</div>

<div class="flex flex-wrap content-center h-64">
    <!-- Centered lines -->
</div>

<div class="flex flex-wrap content-between h-64">
    <!-- Space between lines -->
</div>

<div class="flex flex-wrap content-around h-64">
    <!-- Space around lines -->
</div>

Flex Grow and Shrink

Control Item Growth
<!-- Flex grow -->
<div class="flex">
    <div class="flex-grow">Grows to fill space</div>
    <div>Fixed width</div>
</div>

<!-- Flex shrink -->
<div class="flex">
    <div class="flex-shrink">Can shrink</div>
    <div class="flex-shrink-0">Won't shrink</div>
</div>

<!-- Flex 1 (grow and shrink equally) -->
<div class="flex">
    <div class="flex-1">Equal</div>
    <div class="flex-1">Equal</div>
    <div class="flex-1">Equal</div>
</div>

<!-- Flex auto (grow based on content) -->
<div class="flex">
    <div class="flex-auto">Content-based</div>
    <div class="flex-auto">Content-based</div>
</div>

<!-- Flex none (don't grow or shrink) -->
<div class="flex">
    <div class="flex-none w-32">Fixed 128px</div>
    <div class="flex-1">Fills remaining</div>
</div>

Order

Change Visual Order
<div class="flex">
    <div class="order-3">First in code, third visually</div>
    <div class="order-1">Second in code, first visually</div>
    <div class="order-2">Third in code, second visually</div>
</div>

<!-- Responsive order -->
<div class="flex flex-col md:flex-row">
    <div class="md:order-2">Sidebar (after on desktop)</div>
    <div class="md:order-1">Main content (before on desktop)</div>
</div>

Gap

Space Between Items
<!-- Gap between all items -->
<div class="flex gap-4">
    <div>Item 1</div>
    <div>Item 2</div>
    <div>Item 3</div>
</div>

<!-- Gap X and Y -->
<div class="flex flex-wrap gap-x-4 gap-y-2">
    <div>Item</div>
    <div>Item</div>
</div>

<!-- Responsive gap -->
<div class="flex gap-2 md:gap-4 lg:gap-6">
    <!-- Gap increases with screen size -->
</div>

Practical Examples

Real-World Layouts
<!-- Navigation bar -->
<nav class="flex items-center justify-between p-4 bg-gray-800 text-white">
    <div class="text-xl font-bold">Logo</div>
    <ul class="flex space-x-6">
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact</a></li>
    </ul>
</nav>

<!-- Card with header and footer -->
<div class="flex flex-col h-96 border rounded-lg">
    <header class="p-4 border-b">Card Header</header>
    <main class="flex-1 p-4 overflow-y-auto">
        Content that grows to fill space
    </main>
    <footer class="p-4 border-t bg-gray-50">Card Footer</footer>
</div>

<!-- Sidebar layout -->
<div class="flex h-screen">
    <aside class="w-64 bg-gray-800 text-white p-4">
        Sidebar
    </aside>
    <main class="flex-1 p-4 overflow-y-auto">
        Main content
    </main>
</div>

<!-- Centered modal -->
<div class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
    <div class="bg-white p-6 rounded-lg max-w-md">
        Modal content
    </div>
</div>
Practice Tasks
  • Create a navigation bar with logo on left, links on right.
  • Build a card with fixed header/footer and scrollable content.
  • Make a responsive layout that switches from column to row.
  • Create a perfectly centered modal using flexbox.

Key Takeaways

  • Use flex to create flexible layouts.
  • justify-content controls horizontal alignment.
  • items-* controls vertical alignment.
  • flex-1 makes items grow equally to fill space.
  • gap adds spacing between flex items.
  • Combine with responsive prefixes for adaptive layouts.

What's Next?

Next Topic: Learn about CSS Grid for two-dimensional layouts.

CSS Grid in Tailwind CSS

Build complex responsive layouts with powerful CSS Grid utilities

What is CSS Grid?

CSS Grid is a two-dimensional layout system that allows you to create complex layouts by defining rows and columns. Tailwind provides utility classes that make working with CSS Grid simple and intuitive.

Basic Grid Layout

Simple Grid with Columns
<!-- 3 column grid -->
<div class="grid grid-cols-3 gap-4">
    <div class="bg-blue-500 p-4">Item 1</div>
    <div class="bg-blue-500 p-4">Item 2</div>
    <div class="bg-blue-500 p-4">Item 3</div>
    <div class="bg-blue-500 p-4">Item 4</div>
    <div class="bg-blue-500 p-4">Item 5</div>
    <div class="bg-blue-500 p-4">Item 6</div>
</div>

<!-- 4 column grid -->
<div class="grid grid-cols-4 gap-4">
    <div class="bg-green-500 p-4">1</div>
    <div class="bg-green-500 p-4">2</div>
    <div class="bg-green-500 p-4">3</div>
    <div class="bg-green-500 p-4">4</div>
</div>

Responsive Grid Columns

Mobile-First Responsive Grid
<!-- 1 column on mobile, 2 on tablet, 3 on desktop -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
    <div class="bg-purple-500 p-4">Item 1</div>
    <div class="bg-purple-500 p-4">Item 2</div>
    <div class="bg-purple-500 p-4">Item 3</div>
    <div class="bg-purple-500 p-4">Item 4</div>
    <div class="bg-purple-500 p-4">Item 5</div>
    <div class="bg-purple-500 p-4">Item 6</div>
</div>

<!-- Complex responsive layout -->
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-3">
    <div class="bg-indigo-500 p-4">1</div>
    <div class="bg-indigo-500 p-4">2</div>
    <div class="bg-indigo-500 p-4">3</div>
    <div class="bg-indigo-500 p-4">4</div>
    <div class="bg-indigo-500 p-4">5</div>
    <div class="bg-indigo-500 p-4">6</div>
</div>

Grid Column Spanning

Spanning Multiple Columns
<div class="grid grid-cols-6 gap-4">
    <!-- Span 2 columns -->
    <div class="col-span-2 bg-red-500 p-4">Spans 2 columns</div>
    <div class="col-span-2 bg-red-500 p-4">Spans 2 columns</div>
    <div class="col-span-2 bg-red-500 p-4">Spans 2 columns</div>

    <!-- Span 3 columns -->
    <div class="col-span-3 bg-yellow-500 p-4">Spans 3 columns</div>
    <div class="col-span-3 bg-yellow-500 p-4">Spans 3 columns</div>

    <!-- Span full width -->
    <div class="col-span-6 bg-blue-500 p-4">Spans all 6 columns</div>
</div>

Grid Row Configuration

Grid Rows and Row Spanning
<!-- Define explicit rows -->
<div class="grid grid-cols-3 grid-rows-3 gap-4">
    <div class="row-span-2 bg-pink-500 p-4">Spans 2 rows</div>
    <div class="bg-pink-400 p-4">Item 2</div>
    <div class="bg-pink-400 p-4">Item 3</div>
    <div class="bg-pink-400 p-4">Item 4</div>
    <div class="bg-pink-400 p-4">Item 5</div>
    <div class="row-span-2 bg-pink-500 p-4">Spans 2 rows</div>
    <div class="bg-pink-400 p-4">Item 7</div>
    <div class="bg-pink-400 p-4">Item 8</div>
</div>

<!-- Full height span -->
<div class="grid grid-cols-2 grid-rows-4 gap-4 h-96">
    <div class="row-span-4 bg-teal-500 p-4">Sidebar</div>
    <div class="bg-teal-300 p-4">Content 1</div>
    <div class="bg-teal-300 p-4">Content 2</div>
    <div class="bg-teal-300 p-4">Content 3</div>
    <div class="bg-teal-300 p-4">Content 4</div>
</div>

Gap Utilities

Grid Gaps
<!-- Equal gap on all sides -->
<div class="grid grid-cols-3 gap-4">
    <div class="bg-orange-500 p-4">Item</div>
    <div class="bg-orange-500 p-4">Item</div>
    <div class="bg-orange-500 p-4">Item</div>
</div>

<!-- Different horizontal and vertical gaps -->
<div class="grid grid-cols-3 gap-x-8 gap-y-4">
    <div class="bg-cyan-500 p-4">Item</div>
    <div class="bg-cyan-500 p-4">Item</div>
    <div class="bg-cyan-500 p-4">Item</div>
    <div class="bg-cyan-500 p-4">Item</div>
</div>

<!-- No gap -->
<div class="grid grid-cols-4 gap-0">
    <div class="bg-lime-500 p-4 border">1</div>
    <div class="bg-lime-500 p-4 border">2</div>
    <div class="bg-lime-500 p-4 border">3</div>
    <div class="bg-lime-500 p-4 border">4</div>
</div>

Grid Auto Flow

Controlling Item Placement
<!-- Row auto flow (default) -->
<div class="grid grid-cols-3 grid-flow-row gap-4">
    <div class="col-span-2 bg-violet-500 p-4">1</div>
    <div class="bg-violet-400 p-4">2</div>
    <div class="bg-violet-400 p-4">3</div>
    <div class="bg-violet-400 p-4">4</div>
</div>

<!-- Column auto flow -->
<div class="grid grid-cols-3 grid-rows-3 grid-flow-col gap-4">
    <div class="bg-fuchsia-500 p-4">1</div>
    <div class="bg-fuchsia-500 p-4">2</div>
    <div class="bg-fuchsia-500 p-4">3</div>
    <div class="bg-fuchsia-500 p-4">4</div>
    <div class="bg-fuchsia-500 p-4">5</div>
</div>

<!-- Dense packing -->
<div class="grid grid-cols-3 grid-flow-row-dense gap-4">
    <div class="col-span-2 bg-rose-500 p-4">Wide item</div>
    <div class="bg-rose-400 p-4">2</div>
    <div class="bg-rose-400 p-4">3</div>
    <div class="col-span-2 bg-rose-500 p-4">Wide item</div>
</div>

Practical Grid Layouts

Real-World Grid Examples
<!-- Blog post grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
    <article class="bg-white rounded-lg shadow-md overflow-hidden">
        <img src="image1.jpg" alt="Post" class="w-full h-48 object-cover">
        <div class="p-4">
            <h3 class="font-bold text-xl mb-2">Blog Post Title</h3>
            <p class="text-gray-600">Post description...</p>
        </div>
    </article>
    <!-- More articles... -->
</div>

<!-- Dashboard layout -->
<div class="grid grid-cols-1 lg:grid-cols-4 gap-4">
    <div class="lg:col-span-3 bg-white p-6 rounded">Main content</div>
    <div class="bg-white p-6 rounded">Sidebar</div>
</div>

<!-- Card grid with featured item -->
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
    <div class="col-span-2 row-span-2 bg-blue-500 p-6 rounded">
        Featured Item
    </div>
    <div class="bg-gray-300 p-4 rounded">Item 2</div>
    <div class="bg-gray-300 p-4 rounded">Item 3</div>
    <div class="bg-gray-300 p-4 rounded">Item 4</div>
    <div class="bg-gray-300 p-4 rounded">Item 5</div>
</div>

Grid Template Columns

Custom Column Widths
<!-- Auto columns -->
<div class="grid grid-cols-3 gap-4">
    <div class="bg-emerald-500 p-4">Auto</div>
    <div class="bg-emerald-500 p-4">Auto</div>
    <div class="bg-emerald-500 p-4">Auto</div>
</div>

<!-- Using Tailwind's arbitrary values -->
<div class="grid grid-cols-[200px_1fr_200px] gap-4">
    <div class="bg-sky-500 p-4">200px</div>
    <div class="bg-sky-500 p-4">Flexible</div>
    <div class="bg-sky-500 p-4">200px</div>
</div>

<!-- Fractional units -->
<div class="grid grid-cols-[1fr_2fr_1fr] gap-4">
    <div class="bg-amber-500 p-4">1fr</div>
    <div class="bg-amber-500 p-4">2fr</div>
    <div class="bg-amber-500 p-4">1fr</div>
</div>
Practice Tasks
  • Create a photo gallery grid that displays 1 column on mobile, 2 columns on tablet, and 4 columns on desktop with equal gaps
  • Build a dashboard layout with a sidebar that spans 1 column and main content that spans 3 columns on large screens
  • Design a product grid where the first item spans 2 columns and 2 rows (featured product) while others are regular size
  • Create a masonry-style grid layout using different row spans for various items to create visual interest

Key Takeaways

  • grid-cols-{n}: Creates a grid with n equal columns (1-12)
  • col-span-{n}: Makes an item span across n columns
  • grid-rows-{n}: Defines n explicit rows
  • row-span-{n}: Makes an item span across n rows
  • gap-{size}: Adds spacing between grid items (or use gap-x/gap-y separately)
  • grid-flow-{direction}: Controls how auto-placed items flow (row, col, dense)

What's Next?

Next Topic: Continue to Spacing to learn about padding, margin, and space-between utilities in Tailwind CSS.

Layout Utilities in Tailwind CSS

Control display, position, overflow, and z-index

Display Utilities

Control how elements are displayed with utilities for block, inline, flex, grid, and more.

Display Types
<!-- Block -->
<div class="block">Block element (full width)</div>

<!-- Inline Block -->
<span class="inline-block">Inline block</span>

<!-- Inline -->
<span class="inline">Inline element</span>

<!-- Flex -->
<div class="flex">
    <div>Item 1</div>
    <div>Item 2</div>
</div>

<!-- Grid -->
<div class="grid grid-cols-3">
    <div>Item 1</div>
    <div>Item 2</div>
    <div>Item 3</div>
</div>

<!-- Hidden -->
<div class="hidden">Not visible</div>

<!-- Responsive display -->
<div class="hidden lg:block">Visible on large screens only</div>

Position Utilities

Positioning Elements
<!-- Static (default) -->
<div class="static">Static positioning</div>

<!-- Relative -->
<div class="relative">
    <div class="absolute top-0 right-0">Absolute child</div>
</div>

<!-- Fixed (relative to viewport) -->
<div class="fixed top-0 left-0 right-0 bg-white z-50">
    Fixed header
</div>

<!-- Sticky -->
<div class="sticky top-0 bg-white">
    Sticky navigation
</div>

<!-- Absolute with positioning -->
<div class="relative h-64">
    <div class="absolute top-0 left-0">Top Left</div>
    <div class="absolute top-0 right-0">Top Right</div>
    <div class="absolute bottom-0 left-0">Bottom Left</div>
    <div class="absolute bottom-0 right-0">Bottom Right</div>
    <div class="absolute inset-0 flex items-center justify-center">
        Centered
    </div>
</div>

Top/Right/Bottom/Left

Inset Values
<!-- Individual sides -->
<div class="absolute top-4 right-4">4 from top and right</div>

<!-- Inset (all sides) -->
<div class="absolute inset-0">0 from all sides (full coverage)</div>
<div class="absolute inset-4">1rem from all sides</div>

<!-- Inset X/Y -->
<div class="absolute inset-x-0">0 from left and right</div>
<div class="absolute inset-y-0">0 from top and bottom</div>

<!-- Negative values -->
<div class="absolute -top-4 -left-4">Outside parent</div>

<!-- Percentage values -->
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
    Perfect centering
</div>

Z-Index

Stacking Order
<!-- Predefined z-index values -->
<div class="relative">
    <div class="absolute z-0">Behind (z-index: 0)</div>
    <div class="absolute z-10">Middle (z-index: 10)</div>
    <div class="absolute z-20">Front (z-index: 20)</div>
    <div class="absolute z-50">Higher (z-index: 50)</div>
</div>

<!-- Common z-index values:
     z-0    (0)
     z-10   (10)
     z-20   (20)
     z-30   (30)
     z-40   (40)
     z-50   (50)
     z-auto (auto)
-->

<!-- Modal overlay example -->
<div class="fixed inset-0 bg-black bg-opacity-50 z-40"></div>
<div class="fixed inset-0 flex items-center justify-center z-50">
    <div class="bg-white p-6 rounded-lg">Modal content</div>
</div>

Overflow

Content Overflow
<!-- Visible (default) -->
<div class="overflow-visible">Content can overflow</div>

<!-- Hidden -->
<div class="overflow-hidden">Content is clipped</div>

<!-- Scroll -->
<div class="overflow-scroll h-32">
    Always shows scrollbars
</div>

<!-- Auto -->
<div class="overflow-auto h-32">
    Scrollbars appear when needed
</div>

<!-- X/Y axis control -->
<div class="overflow-x-auto overflow-y-hidden">
    Horizontal scroll only
</div>

<!-- Scrollable card -->
<div class="max-h-96 overflow-y-auto border rounded p-4">
    <p>Long content...</p>
    <p>More content...</p>
</div>

Floats

Float Utilities
<!-- Float left -->
<img class="float-left mr-4 mb-4" src="image.jpg" alt="Image">
<p>Text wraps around floated image...</p>

<!-- Float right -->
<img class="float-right ml-4 mb-4" src="image.jpg" alt="Image">
<p>Text wraps around floated image...</p>

<!-- Clear floats -->
<div class="clear-both">Clears both floats</div>
<div class="clear-left">Clears left float</div>
<div class="clear-right">Clears right float</div>

Object Fit

Image/Video Sizing
<!-- Contain -->
<img class="w-full h-64 object-contain" src="image.jpg" alt="Contained">

<!-- Cover -->
<img class="w-full h-64 object-cover" src="image.jpg" alt="Covered">

<!-- Fill -->
<img class="w-full h-64 object-fill" src="image.jpg" alt="Filled">

<!-- None -->
<img class="object-none" src="image.jpg" alt="Original size">

<!-- Object position -->
<img class="object-cover object-center" src="image.jpg" alt="Centered">
<img class="object-cover object-top" src="image.jpg" alt="Top aligned">
<img class="object-cover object-bottom" src="image.jpg" alt="Bottom aligned">

Visibility

Visible vs Hidden
<!-- Visible (default) -->
<div class="visible">Visible element</div>

<!-- Invisible (takes up space) -->
<div class="invisible">Hidden but space reserved</div>

<!-- Display none (no space) -->
<div class="hidden">Completely hidden</div>

<!-- Difference:
     invisible: visibility: hidden (space preserved)
     hidden: display: none (no space taken)
-->

Practical Example

Fixed Header with Content
<!-- Fixed header -->
<header class="fixed top-0 left-0 right-0 bg-white shadow-md z-50 h-16">
    <div class="container mx-auto px-4 h-full flex items-center justify-between">
        <div class="text-xl font-bold">Logo</div>
        <nav class="flex space-x-4">
            <a href="#">Home</a>
            <a href="#">About</a>
        </nav>
    </div>
</header>

<!-- Main content with top padding to account for fixed header -->
<main class="pt-16">
    <div class="container mx-auto px-4">
        <!-- Content -->
    </div>
</main>

<!-- Sticky sidebar -->
<div class="flex">
    <aside class="w-64 sticky top-20 h-screen overflow-y-auto">
        Sticky sidebar
    </aside>
    <main class="flex-1">
        Long scrolling content
    </main>
</div>
Practice Tasks
  • Create a fixed header that stays at the top when scrolling.
  • Build a modal with backdrop overlay using z-index.
  • Make a sticky sidebar that scrolls with content.
  • Create an image gallery with object-cover for consistent sizing.

Key Takeaways

  • Display utilities control how elements are rendered (block, flex, grid).
  • Position utilities: static, relative, absolute, fixed, sticky.
  • Use top/right/bottom/left with positioned elements.
  • Z-index controls stacking order of overlapping elements.
  • Overflow controls how content that exceeds bounds is handled.
  • Object-fit controls image sizing within containers.

What's Next?

Next Topic: Master Flexbox utilities for flexible layouts.

Container Utility in Tailwind CSS

Center and constrain content with responsive max-widths

What is Container?

The container class sets the max-width of an element to match the min-width of the current breakpoint, making it easy to create centered, responsive layouts.

Basic Usage

Simple Container
<!-- Basic container -->
<div class="container">
    <!-- Content -->
</div>

<!-- Container with horizontal centering -->
<div class="container mx-auto">
    <!-- Content is centered -->
</div>

<!-- Container with padding -->
<div class="container mx-auto px-4">
    <!-- Content has left and right padding -->
</div>

Container Breakpoints

Responsive Max-Widths
/* Default container breakpoints */
.container {
  width: 100%;
}

/* sm (640px) and up */
@media(min-width: 640px) {
  .container {
    max-width: 640px;
  }
}

/* md (768px) and up */
@media(min-width: 768px) {
  .container {
    max-width: 768px;
  }
}

/* lg (1024px) and up */
@media(min-width: 1024px) {
  .container {
    max-width: 1024px;
  }
}

/* xl (1280px) and up */
@media(min-width: 1280px) {
  .container {
    max-width: 1280px;
  }
}

/* 2xl (1536px) and up */
@media(min-width: 1536px) {
  .container {
    max-width: 1536px;
  }
}

Center Container

Horizontal Centering
<!-- Center with margin auto -->
<div class="container mx-auto">
    Centered container
</div>

<!-- Full width container (not centered) -->
<div class="container">
    Full width up to max-width
</div>

<!-- Center with custom margins -->
<div class="container mx-auto my-8">
    Centered with vertical margins
</div>

Container Padding

Add Horizontal Padding
<!-- Fixed padding -->
<div class="container mx-auto px-4">
    1rem padding on each side
</div>

<!-- Responsive padding -->
<div class="container mx-auto px-4 sm:px-6 lg:px-8">
    Padding increases with screen size
</div>

<!-- Full padding control -->
<div class="container mx-auto px-4 py-8">
    Horizontal and vertical padding
</div>

Custom Container

Configure Container
// tailwind.config.js
module.exports = {
  theme: {
    container: {
      // Center by default
      center: true,

      // Add horizontal padding by default
      padding: '2rem',

      // Or responsive padding
      padding: {
        DEFAULT: '1rem',
        sm: '2rem',
        lg: '4rem',
        xl: '5rem',
        '2xl': '6rem',
      },
    },
  },
}
<!-- Now container is automatically centered with padding -->
<div class="container">
    Automatically centered with responsive padding
</div>

Custom Max-Widths

Override Container Sizes
// tailwind.config.js
module.exports = {
  theme: {
    container: {
      center: true,
      padding: '2rem',
      screens: {
        sm: '100%',
        md: '100%',
        lg: '1024px',
        xl: '1280px',
        '2xl': '1400px', // Custom max-width
      },
    },
  },
}

Container vs Max-Width

When to Use Each
<!-- Container: Responsive breakpoints -->
<div class="container mx-auto px-4">
    Max-width changes at each breakpoint
</div>

<!-- Max-width: Fixed maximum -->
<div class="max-w-7xl mx-auto px-4">
    Always max-width: 80rem (1280px)
</div>

<!-- Common max-width values:
     max-w-sm    (24rem / 384px)
     max-w-md    (28rem / 448px)
     max-w-lg    (32rem / 512px)
     max-w-xl    (36rem / 576px)
     max-w-2xl   (42rem / 672px)
     max-w-3xl   (48rem / 768px)
     max-w-4xl   (56rem / 896px)
     max-w-5xl   (64rem / 1024px)
     max-w-6xl   (72rem / 1152px)
     max-w-7xl   (80rem / 1280px)
     max-w-full  (100%)
-->

Practical Examples

Common Layout Patterns
<!-- Full-width header with contained content -->
<header class="bg-gray-800 text-white">
    <div class="container mx-auto px-4 py-6">
        <nav class="flex justify-between items-center">
            <div class="text-xl font-bold">Logo</div>
            <ul class="flex space-x-4">
                <li><a href="#">Home</a></li>
                <li><a href="#">About</a></li>
            </ul>
        </nav>
    </div>
</header>

<!-- Main content area -->
<main class="container mx-auto px-4 py-8">
    <h1 class="text-3xl font-bold mb-4">Page Title</h1>
    <p>Content goes here...</p>
</main>

<!-- Full-width footer -->
<footer class="bg-gray-900 text-white mt-12">
    <div class="container mx-auto px-4 py-8">
        <p>© 2024 My Website</p>
    </div>
</footer>

Multiple Containers

Nested and Side-by-Side
<!-- Multiple sections with containers -->
<section class="bg-gray-100 py-12">
    <div class="container mx-auto px-4">
        <h2 class="text-2xl font-bold mb-6">Features</h2>
        <!-- Feature grid -->
    </div>
</section>

<section class="py-12">
    <div class="container mx-auto px-4">
        <h2 class="text-2xl font-bold mb-6">Testimonials</h2>
        <!-- Testimonial cards -->
    </div>
</section>

<!-- Narrower container for reading content -->
<article class="max-w-3xl mx-auto px-4 py-12">
    <h1 class="text-4xl font-bold mb-4">Blog Post Title</h1>
    <p class="text-lg leading-relaxed">
        Blog content with optimal reading width...
    </p>
</article>
Practice Tasks
  • Create a page layout with header, main, and footer using container.
  • Configure container with centering and padding in config file.
  • Build a blog post layout with max-w-3xl for optimal reading.
  • Test container behavior at different screen sizes.

Key Takeaways

  • Container sets responsive max-width at each breakpoint.
  • Always use mx-auto to center containers horizontally.
  • Add px-4 or responsive padding for proper spacing.
  • Configure default centering and padding in tailwind.config.js.
  • Use max-w-* classes for fixed maximum widths.
  • Container is ideal for main layout, max-w-* for content sections.

What's Next?

Next Topic: Learn about Layout utilities including display, position, and z-index.

Customization in Tailwind CSS

Configure and extend Tailwind to match your design system

Understanding Customization

Tailwind CSS is highly customizable through the tailwind.config.js file. You can customize colors, spacing, fonts, breakpoints, and more. The configuration uses a robust system that allows you to extend or completely override the default theme.

Basic Configuration File

tailwind.config.js Structure
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./resources/**/*.blade.php",
    "./resources/**/*.js",
    "./resources/**/*.vue",
  ],
  darkMode: 'class',
  theme: {
    extend: {
      // Your customizations here
    },
  },
  plugins: [],
}

Extending Colors

Custom Color Palette
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        // Add custom colors
        brand: {
          50: '#f0f9ff',
          100: '#e0f2fe',
          200: '#bae6fd',
          300: '#7dd3fc',
          400: '#38bdf8',
          500: '#0ea5e9',
          600: '#0284c7',
          700: '#0369a1',
          800: '#075985',
          900: '#0c4a6e',
        },
        accent: '#ff6b6b',
        success: '#51cf66',
        warning: '#ffd43b',
        danger: '#ff6b6b',
      },
    },
  },
}

Custom Spacing Scale

Extending Spacing
module.exports = {
  theme: {
    extend: {
      spacing: {
        '72': '18rem',
        '84': '21rem',
        '96': '24rem',
        '128': '32rem',
      },
    },
  },
}

// Usage: w-72, h-84, p-96, m-128

Custom Fonts

Font Family Configuration
module.exports = {
  theme: {
    extend: {
      fontFamily: {
        sans: ['Inter', 'system-ui', 'sans-serif'],
        serif: ['Merriweather', 'serif'],
        mono: ['Fira Code', 'monospace'],
        display: ['Playfair Display', 'serif'],
      },
    },
  },
}

// Usage: font-sans, font-serif, font-mono, font-display

Custom Breakpoints

Responsive Breakpoints
module.exports = {
  theme: {
    screens: {
      'xs': '475px',
      'sm': '640px',
      'md': '768px',
      'lg': '1024px',
      'xl': '1280px',
      '2xl': '1536px',
      '3xl': '1920px',
    },
  },
}

// Usage: xs:text-sm, 3xl:text-6xl

Extending Box Shadows

Custom Shadows
module.exports = {
  theme: {
    extend: {
      boxShadow: {
        'soft': '0 2px 15px -3px rgba(0, 0, 0, 0.07)',
        'glow': '0 0 15px rgba(59, 130, 246, 0.5)',
        'inner-lg': 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.1)',
      },
    },
  },
}

// Usage: shadow-soft, shadow-glow, shadow-inner-lg

Custom Border Radius

Border Radius Values
module.exports = {
  theme: {
    extend: {
      borderRadius: {
        '4xl': '2rem',
        '5xl': '2.5rem',
      },
    },
  },
}

// Usage: rounded-4xl, rounded-5xl

Custom Animations

Keyframe Animations
module.exports = {
  theme: {
    extend: {
      keyframes: {
        wiggle: {
          '0%, 100%': { transform: 'rotate(-3deg)' },
          '50%': { transform: 'rotate(3deg)' },
        },
        fadeIn: {
          '0%': { opacity: '0' },
          '100%': { opacity: '1' },
        },
        slideUp: {
          '0%': { transform: 'translateY(100%)' },
          '100%': { transform: 'translateY(0)' },
        },
      },
      animation: {
        wiggle: 'wiggle 1s ease-in-out infinite',
        fadeIn: 'fadeIn 0.5s ease-in',
        slideUp: 'slideUp 0.5s ease-out',
      },
    },
  },
}

// Usage: animate-wiggle, animate-fadeIn, animate-slideUp

Theme Overriding vs Extending

Complete Override
// EXTENDING (recommended) - adds to defaults
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: '#3490dc',
      },
    },
  },
}
// Still have access to blue-500, red-600, etc. + primary

// OVERRIDING - replaces defaults
module.exports = {
  theme: {
    colors: {
      primary: '#3490dc',
      secondary: '#ffed4e',
    },
  },
}
// ONLY have primary and secondary, no blue-500, etc.

Accessing Config Values

Using theme() Function
/* In your CSS */
.custom-element {
  color: theme('colors.brand.500');
  padding: theme('spacing.4');
  border-radius: theme('borderRadius.lg');
}

/* With default fallback */
.another-element {
  color: theme('colors.custom', #000);
}

Arbitrary Values

One-Off Custom Values
<!-- Use square brackets for arbitrary values -->
<div class=\"w-[347px]\">Exact width</div>
<div class=\"bg-[#1da1f2]\">Twitter blue</div>
<div class=\"text-[22px]\">Specific font size</div>
<div class=\"top-[117px]\">Precise positioning</div>
<div class=\"grid-cols-[1fr_500px_2fr]\">Custom grid</div>

<!-- With CSS variables -->
<div class=\"bg-[var(--my-color)]\">CSS variable</div>

Complete Configuration Example

Production-Ready Config
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './resources/**/*.blade.php',
    './resources/**/*.js',
    './resources/**/*.vue',
  ],
  darkMode: 'class',
  theme: {
    extend: {
      colors: {
        brand: {
          50: '#eff6ff',
          100: '#dbeafe',
          200: '#bfdbfe',
          300: '#93c5fd',
          400: '#60a5fa',
          500: '#3b82f6',
          600: '#2563eb',
          700: '#1d4ed8',
          800: '#1e40af',
          900: '#1e3a8a',
        },
      },
      fontFamily: {
        sans: ['Inter', 'system-ui', 'sans-serif'],
      },
      spacing: {
        '128': '32rem',
        '144': '36rem',
      },
      borderRadius: {
        '4xl': '2rem',
      },
      boxShadow: {
        'soft': '0 2px 15px -3px rgba(0, 0, 0, 0.07)',
      },
      animation: {
        'fade-in': 'fadeIn 0.5s ease-in',
      },
      keyframes: {
        fadeIn: {
          '0%': { opacity: '0' },
          '100%': { opacity: '1' },
        },
      },
    },
  },
  plugins: [],
}
Practice Tasks
  • Create a custom color palette for your brand with shades from 50-900
  • Extend the spacing scale with custom values (e.g., 72, 84, 96, 128)
  • Configure custom font families and use them in your project
  • Create a custom animation with keyframes and apply it to an element

Key Takeaways

  • extend: Add to default theme without losing built-in utilities
  • Override: Replace default theme values completely (use cautiously)
  • Arbitrary values: Use [value] syntax for one-off custom values
  • theme() function: Access config values in CSS
  • Organization: Keep config organized and documented
  • Design tokens: Use config as single source of truth for design system

What's Next?

Next Topic: Continue to Functions & Directives to learn about Tailwind's CSS functions and directives.

Tailwind CSS Plugins

Extend Tailwind with official and custom plugins

Understanding Plugins

Plugins allow you to register new styles for Tailwind to inject into the user's stylesheet. They can add new utilities, components, base styles, or variants. Tailwind provides several official plugins, and you can also create your own.

Official Forms Plugin

Install & Configure Forms
# Install the forms plugin
npm install -D @tailwindcss/forms
// tailwind.config.js
module.exports = {
  plugins: [
    require('@tailwindcss/forms'),
  ],
}
<!-- Automatically styled form elements -->
<form>
  <input type=\"email\" placeholder=\"Email\" class=\"rounded-md\">
  <input type=\"password\" placeholder=\"Password\" class=\"rounded-md\">

  <select class=\"rounded-md\">
    <option>Option 1</option>
    <option>Option 2</option>
  </select>

  <textarea rows=\"4\" class=\"rounded-md\"></textarea>

  <label class=\"flex items-center\">
    <input type=\"checkbox\" class=\"rounded\">
    <span class=\"ml-2\">Remember me</span>
  </label>
</form>

Official Typography Plugin

Install & Use Typography
# Install typography plugin
npm install -D @tailwindcss/typography
// tailwind.config.js
module.exports = {
  plugins: [
    require('@tailwindcss/typography'),
  ],
}
<!-- Beautiful typography with prose classes -->
<article class=\"prose lg:prose-xl\">
  <h1>Article Title</h1>
  <p>This content is automatically styled with beautiful typography.</p>
  <h2>Subheading</h2>
  <p>Links, lists, and code blocks are all styled consistently.</p>
  <ul>
    <li>Automatic spacing</li>
    <li>Beautiful defaults</li>
    <li>Responsive sizing</li>
  </ul>
</article>

<!-- Dark mode typography -->
<article class=\"prose dark:prose-invert\">
  <h1>Dark Mode Article</h1>
  <p>Automatically adapts to dark mode.</p>
</article>

Typography Plugin Modifiers

Prose Variants
<!-- Size variants -->
<div class=\"prose prose-sm\">Small prose</div>
<div class=\"prose prose-base\">Base prose</div>
<div class=\"prose prose-lg\">Large prose</div>
<div class=\"prose prose-xl\">Extra large prose</div>
<div class=\"prose prose-2xl\">2XL prose</div>

<!-- Color variants -->
<div class=\"prose prose-slate\">Slate theme</div>
<div class=\"prose prose-gray\">Gray theme</div>
<div class=\"prose prose-zinc\">Zinc theme</div>
<div class=\"prose prose-stone\">Stone theme</div>

<!-- Element-specific overrides -->
<div class=\"prose prose-headings:text-blue-600 prose-a:text-blue-500\">
  <h2>Blue headings</h2>
  <a href=\"#\">Blue links</a>
</div>

Official Aspect Ratio Plugin

Install & Use Aspect Ratio
# Install aspect-ratio plugin
npm install -D @tailwindcss/aspect-ratio
// tailwind.config.js
module.exports = {
  plugins: [
    require('@tailwindcss/aspect-ratio'),
  ],
}
<!-- Fixed aspect ratios -->
<div class=\"aspect-w-16 aspect-h-9\">
  <iframe src=\"https://www.youtube.com/embed/dQw4w9WgXcQ\"></iframe>
</div>

<div class=\"aspect-w-4 aspect-h-3\">
  <img src=\"image.jpg\" alt=\"4:3 image\" class=\"object-cover\">
</div>

<div class=\"aspect-w-1 aspect-h-1\">
  <img src=\"profile.jpg\" alt=\"Square\" class=\"object-cover\">
</div>

Official Line Clamp Plugin

Install & Use Line Clamp
# Install line-clamp plugin (built-in v3.3+)
npm install -D @tailwindcss/line-clamp
<!-- Truncate text to specific lines -->
<p class=\"line-clamp-1\">
  This text will be truncated to a single line with an ellipsis...
</p>

<p class=\"line-clamp-2\">
  This longer text will be truncated to two lines.
  Any additional content beyond two lines will be hidden with an ellipsis.
</p>

<p class=\"line-clamp-3\">
  Three lines of text maximum.
  Perfect for article previews.
  Keeps layouts consistent.
  Extra content hidden.
</p>

<!-- Responsive line clamping -->
<p class=\"line-clamp-2 lg:line-clamp-none\">
  Clamped on mobile, full text on large screens
</p>

Creating a Simple Plugin

Basic Plugin Structure
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities, addComponents, theme }) {
      // Add custom utilities
      const newUtilities = {
        '.text-shadow': {
          textShadow: '2px 2px 4px rgba(0, 0, 0, 0.1)',
        },
        '.text-shadow-md': {
          textShadow: '4px 4px 8px rgba(0, 0, 0, 0.15)',
        },
        '.text-shadow-lg': {
          textShadow: '6px 6px 12px rgba(0, 0, 0, 0.2)',
        },
        '.text-shadow-none': {
          textShadow: 'none',
        },
      }

      addUtilities(newUtilities, ['responsive', 'hover'])
    })
  ],
}

// Usage: text-shadow, hover:text-shadow-md, lg:text-shadow-lg

Adding Components with Plugin

Component Plugin
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addComponents, theme }) {
      const buttons = {
        '.btn': {
          padding: `${theme('spacing.2')} ${theme('spacing.4')}`,
          borderRadius: theme('borderRadius.md'),
          fontWeight: theme('fontWeight.semibold'),
          transition: 'all 0.2s',
        },
        '.btn-primary': {
          backgroundColor: theme('colors.blue.500'),
          color: theme('colors.white'),
          '&:hover': {
            backgroundColor: theme('colors.blue.600'),
          },
        },
        '.btn-secondary': {
          backgroundColor: theme('colors.gray.500'),
          color: theme('colors.white'),
          '&:hover': {
            backgroundColor: theme('colors.gray.600'),
          },
        },
      }

      addComponents(buttons)
    })
  ],
}

Adding Custom Variants

Variant Plugin
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addVariant }) {
      // Add optional variant
      addVariant('optional', '&:optional')

      // Add invalid variant
      addVariant('invalid', '&:invalid')

      // Add hocus variant (hover + focus)
      addVariant('hocus', ['&:hover', '&:focus'])

      // Add child variant
      addVariant('child', '& > *')

      // Add not-first variant
      addVariant('not-first', '&:not(:first-child)')
    })
  ],
}

// Usage:
// optional:border-gray-300
// invalid:border-red-500
// hocus:bg-blue-500
// child:p-4
// not-first:mt-4

Accessing Theme Values

Using Theme in Plugins
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities, theme, e }) {
      // Generate utilities from theme
      const colors = theme('colors')
      const borderUtilities = {}

      Object.keys(colors).forEach(color => {
        if (typeof colors[color] === 'object') {
          Object.keys(colors[color]).forEach(shade => {
            borderUtilities[`.border-t-${e(`${color}-${shade}`)}`] = {
              borderTopColor: colors[color][shade],
            }
          })
        }
      })

      addUtilities(borderUtilities)
    })
  ],
}

Advanced Plugin Features

Complete Plugin Example
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities, addComponents, addBase, addVariant, theme }) {
      // Add base styles
      addBase({
        'h1': { fontSize: theme('fontSize.4xl') },
        'h2': { fontSize: theme('fontSize.3xl') },
      })

      // Add components
      addComponents({
        '.card': {
          backgroundColor: theme('colors.white'),
          borderRadius: theme('borderRadius.lg'),
          padding: theme('spacing.6'),
          boxShadow: theme('boxShadow.lg'),
        },
      })

      // Add utilities with variants
      addUtilities({
        '.content-auto': {
          contentVisibility: 'auto',
        },
        '.content-hidden': {
          contentVisibility: 'hidden',
        },
        '.content-visible': {
          contentVisibility: 'visible',
        },
      }, ['responsive'])

      // Add custom variants
      addVariant('third', '&:nth-child(3)')
      addVariant('not-last', '&:not(:last-child)')
    })
  ],
}

External Plugin Development

Separate Plugin File
// plugins/gradients.js
const plugin = require('tailwindcss/plugin')

module.exports = plugin(function({ addUtilities, theme, e }) {
  const gradients = {
    '.bg-gradient-rainbow': {
      backgroundImage: 'linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet)',
    },
    '.bg-gradient-fire': {
      backgroundImage: 'linear-gradient(45deg, #ff0000, #ff7f00, #ffff00)',
    },
    '.bg-gradient-ocean': {
      backgroundImage: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
    },
  }

  addUtilities(gradients, ['responsive', 'hover'])
}, {
  theme: {
    extend: {
      // Plugin can extend theme
    }
  }
})

// tailwind.config.js
module.exports = {
  plugins: [
    require('./plugins/gradients'),
  ],
}

Plugin Configuration Options

Configurable Plugins
// tailwind.config.js
module.exports = {
  plugins: [
    // Forms plugin with custom strategy
    require('@tailwindcss/forms')({
      strategy: 'class', // or 'base'
    }),

    // Typography with custom className
    require('@tailwindcss/typography')({
      className: 'wysiwyg', // Instead of 'prose'
    }),

    // Custom plugin with options
    require('./plugins/custom')({
      prefix: 'tw-',
      important: true,
    }),
  ],
}
Practice Tasks
  • Install @tailwindcss/forms and style a complete form
  • Use @tailwindcss/typography to create a blog post layout
  • Create a custom plugin that adds text-shadow utilities
  • Build a plugin that generates custom gradient utilities

Key Takeaways

  • Official plugins: Forms, Typography, Aspect Ratio, Line Clamp
  • addUtilities: Add utility classes with variant support
  • addComponents: Add reusable component classes
  • addVariant: Create custom state variants
  • theme(): Access config values in plugins
  • Separate files: Organize complex plugins in separate modules

What's Next?

Next Topic: Continue to Optimization to learn about optimizing Tailwind for production.

Functions & Directives

Master Tailwind's directives and functions for powerful customization

Understanding Directives

Tailwind CSS provides special @ directives that allow you to inject base styles, components, and utilities into your CSS. These directives are essential for building custom components and extending Tailwind's functionality.

@tailwind Directive

Inject Tailwind Layers
/* app.css or main.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Base: Preflight, browser resets */
/* Components: Custom component classes */
/* Utilities: All utility classes */

@layer Directive

Organize Custom Styles
@layer base {
  h1 {
    @apply text-4xl font-bold;
  }
  h2 {
    @apply text-3xl font-semibold;
  }
  a {
    @apply text-blue-600 hover:text-blue-800;
  }
}

@layer components {
  .btn-primary {
    @apply bg-blue-500 text-white px-4 py-2 rounded;
    @apply hover:bg-blue-600 transition-colors;
  }
  .card {
    @apply bg-white rounded-lg shadow-md p-6;
  }
}

@layer utilities {
  .text-shadow {
    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
  }
  .content-auto {
    content-visibility: auto;
  }
}

@apply Directive

Compose Utilities
/* Extract component patterns */
.btn {
  @apply px-4 py-2 rounded font-medium;
  @apply transition-colors duration-200;
  @apply focus:outline-none focus:ring-2;
}

.btn-blue {
  @apply btn bg-blue-500 text-white;
  @apply hover:bg-blue-600;
  @apply focus:ring-blue-300;
}

.btn-red {
  @apply btn bg-red-500 text-white;
  @apply hover:bg-red-600;
  @apply focus:ring-red-300;
}

/* Form controls */
.form-input {
  @apply block w-full px-3 py-2 border border-gray-300;
  @apply rounded-md shadow-sm;
  @apply focus:ring-blue-500 focus:border-blue-500;
}

theme() Function

Access Config Values
/* Access theme values from config */
.custom-element {
  color: theme('colors.blue.500');
  padding: theme('spacing.4');
  border-radius: theme('borderRadius.lg');
  font-family: theme('fontFamily.sans');
}

/* With default fallbacks */
.fallback-example {
  color: theme('colors.custom', #000000);
  width: theme('width.custom', 100%);
}

/* Nested values */
.nested {
  background-color: theme('backgroundColor.gray.50');
  box-shadow: theme('boxShadow.lg');
}

screen() Function

Media Query Helper
/* Use breakpoints from config */
@media screen(sm) {
  .responsive-element {
    display: flex;
  }
}

@media screen(md) {
  .container {
    max-width: theme('screens.md');
  }
}

/* Custom media queries with theme values */
@media(min-width: theme('screens.lg')) {
  .large-screen {
    grid-template-columns: repeat(3, 1fr);
  }
}

@config Directive

Inline Configuration
@config \"./tailwind.admin.config.js\";

/* Use a different config file for this CSS */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Useful for multiple themes or admin panels */

@variants Directive (Legacy)

Custom Variants (v2.x)
/* Modern approach: use arbitrary variants */
.custom-utility {
  @apply hover:bg-blue-500;
  @apply focus:ring-2;
  @apply dark:bg-gray-800;
}

/* Or define in config */
// tailwind.config.js
module.exports = {
  plugins: [
    plugin(function({ addVariant }) {
      addVariant('optional', '&:optional');
      addVariant('hocus', ['&:hover', '&:focus']);
    })
  ]
}

/* Usage: optional:border-gray-300, hocus:bg-blue-500 */

@responsive Directive (Legacy)

Generate Responsive Variants
/* Modern approach: utilities are responsive by default */
@layer utilities {
  .content-auto {
    content-visibility: auto;
  }
  /* Can use: sm:content-auto, md:content-auto, etc. */
}

/* In Tailwind v3+, all utilities are automatically responsive */

Combining Directives

Complete Component Pattern
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  /* Typography defaults */
  h1, h2, h3, h4, h5, h6 {
    @apply font-bold text-gray-900;
  }

  body {
    @apply bg-gray-50 text-gray-900;
  }
}

@layer components {
  /* Button system */
  .btn {
    @apply inline-flex items-center justify-center;
    @apply px-4 py-2 border border-transparent;
    @apply text-base font-medium rounded-md;
    @apply focus:outline-none focus:ring-2 focus:ring-offset-2;
    @apply transition-colors duration-200;
  }

  .btn-lg {
    @apply btn px-6 py-3 text-lg;
  }

  /* Card component */
  .card {
    @apply bg-white rounded-lg shadow;
    @apply overflow-hidden;
  }

  .card-header {
    @apply px-6 py-4 border-b border-gray-200;
    @apply bg-gray-50;
  }

  .card-body {
    @apply px-6 py-4;
  }
}

@layer utilities {
  /* Custom utilities */
  .text-shadow-sm {
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  }

  .text-shadow {
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  }

  .filter-none {
    filter: none;
  }
}

Using theme() with calc()

Dynamic Calculations
.custom-spacing {
  /* Calculate based on theme values */
  margin-top: calc(theme('spacing.4') * 2);
  padding: calc(theme('spacing.2') + 4px);
  width: calc(100% - theme('spacing.8'));
}

.responsive-container {
  max-width: calc(theme('screens.lg') - theme('spacing.8'));
}

Advanced @apply Usage

Complex Component Patterns
@layer components {
  /* Alert component system */
  .alert {
    @apply p-4 rounded-md border;
  }

  .alert-success {
    @apply alert bg-green-50 border-green-200 text-green-800;
  }

  .alert-error {
    @apply alert bg-red-50 border-red-200 text-red-800;
  }

  .alert-warning {
    @apply alert bg-yellow-50 border-yellow-200 text-yellow-800;
  }

  /* Form group pattern */
  .form-group {
    @apply mb-4;
  }

  .form-group label {
    @apply block text-sm font-medium text-gray-700 mb-1;
  }

  .form-group input,
  .form-group textarea,
  .form-group select {
    @apply block w-full px-3 py-2 border border-gray-300;
    @apply rounded-md shadow-sm;
    @apply focus:ring-blue-500 focus:border-blue-500;
  }

  .form-group input:invalid {
    @apply border-red-500 focus:ring-red-500 focus:border-red-500;
  }
}

Best Practices

Directive Usage Guidelines
/* DO: Use @layer to control specificity */
@layer components {
  .btn {
    @apply px-4 py-2 rounded;
  }
}

/* DON'T: Complex logic in @apply */
/* Keep @apply simple and readable */
.bad-example {
  /* Too complex, hard to maintain */
  @apply flex items-center justify-between px-4 py-2 bg-gradient-to-r from-blue-500 to-purple-600 text-white font-bold rounded-lg shadow-xl hover:shadow-2xl transform hover:-translate-y-1 transition-all duration-300;
}

/* DO: Break into smaller components */
.good-example {
  @apply flex items-center justify-between;
  @apply px-4 py-2 rounded-lg;
  @apply bg-gradient-to-r from-blue-500 to-purple-600;
  @apply text-white font-bold shadow-xl;
  @apply hover:shadow-2xl hover:-translate-y-1;
  @apply transition-all duration-300;
}

/* DO: Use theme() for consistency */
.consistent {
  color: theme('colors.primary.500');
  /* NOT: color: #3b82f6; */
}
Practice Tasks
  • Create a custom button component using @apply with hover and focus states
  • Use @layer to organize base styles, components, and utilities
  • Access theme values using theme() function in custom CSS
  • Build a complete form component system with @layer components

Key Takeaways

  • @tailwind: Inject base, components, and utilities layers
  • @layer: Organize custom styles and control specificity
  • @apply: Extract repeating utility patterns into components
  • theme(): Access config values for consistency
  • screen(): Use breakpoints in custom media queries
  • Keep it simple: Don't over-engineer with @apply, balance with inline utilities

What's Next?

Next Topic: Continue to Plugins to learn about official Tailwind plugins and creating custom ones.

Extracting Components in Tailwind CSS

Create reusable components with @apply and component extraction

Understanding Component Extraction

While Tailwind encourages utility-first approach, sometimes you need to extract repeated patterns into reusable components. Tailwind provides the @apply directive for this purpose, allowing you to compose utility classes into custom CSS classes.

Using @apply Directive

Basic @apply Usage
/* styles.css */

/* Button component */
.btn {
  @apply px-4 py-2 rounded font-medium transition;
}

.btn-primary {
  @apply bg-blue-600 text-white hover:bg-blue-700;
}

.btn-secondary {
  @apply bg-gray-200 text-gray-900 hover:bg-gray-300;
}

/* Card component */
.card {
  @apply bg-white rounded-lg shadow-md p-6;
}

.card-header {
  @apply text-xl font-bold mb-4;
}

.card-body {
  @apply text-gray-600;
}
Using Extracted Components
<!-- Now use the extracted classes -->
<button class=\"btn btn-primary\">
    Primary Button
</button>

<button class=\"btn btn-secondary\">
    Secondary Button
</button>

<div class=\"card\">
    <h3 class=\"card-header\">Card Title</h3>
    <p class=\"card-body\">Card content goes here.</p>\n</div>

Component Layers

Using @layer Directive
/* Organize components in layers */

@layer components {
  .btn {
    @apply px-4 py-2 rounded font-medium transition;
  }

  .btn-lg {
    @apply px-6 py-3 text-lg;
  }

  .btn-sm {
    @apply px-3 py-1 text-sm;
  }
}

@layer utilities {
  .content-auto {
    content-visibility: auto;
  }

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

  .scrollbar-hide::-webkit-scrollbar {
    display: none;
  }
}

Extracting Form Components

Form Input Patterns
@layer components {
  .form-input {
    @apply w-full px-4 py-2 border border-gray-300 rounded-lg;
    @apply focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent;
    @apply transition;
  }

  .form-label {
    @apply block text-sm font-medium text-gray-700 mb-2;
  }

  .form-error {
    @apply text-red-600 text-sm mt-1;
  }

  .form-select {
    @apply w-full px-4 py-2 border border-gray-300 rounded-lg;
    @apply focus:outline-none focus:ring-2 focus:ring-blue-500;
    @apply bg-white;
  }

  .form-checkbox {
    @apply w-4 h-4 text-blue-600 border-gray-300 rounded;
    @apply focus:ring-2 focus:ring-blue-500;
  }
}

Responsive Component Extraction

Responsive Patterns
@layer components {
  .container-custom {
    @apply w-full mx-auto px-4;
    @apply sm:px-6 lg:px-8;
    @apply max-w-7xl;
  }

  .grid-auto {
    @apply grid gap-6;
    @apply grid-cols-1 sm:grid-cols-2 lg:grid-cols-3;
  }

  .hero-text {
    @apply text-3xl font-bold;
    @apply md:text-4xl lg:text-5xl;
  }
}

Complex Component Patterns

Advanced Component Extraction
@layer components {
  /* Alert components */
  .alert {
    @apply p-4 rounded-lg border-l-4;
  }

  .alert-success {
    @apply bg-green-50 border-green-500 text-green-900;
  }

  .alert-warning {
    @apply bg-yellow-50 border-yellow-500 text-yellow-900;
  }

  .alert-error {
    @apply bg-red-50 border-red-500 text-red-900;
  }

  /* Badge components */
  .badge {
    @apply inline-block px-3 py-1 text-sm font-medium rounded-full;
  }

  .badge-primary {
    @apply bg-blue-100 text-blue-800;
  }

  .badge-success {
    @apply bg-green-100 text-green-800;
  }

  /* Navigation link */
  .nav-link {
    @apply px-4 py-2 rounded-lg transition;
    @apply text-gray-700 hover:text-blue-600 hover:bg-blue-50;
  }

  .nav-link-active {
    @apply bg-blue-50 text-blue-600 font-medium;
  }
}

When to Extract vs Inline

Decision Guidelines
<!-- DON'T extract single-use patterns -->
<!-- This is fine as inline utilities -->
<div class=\"bg-white p-6 rounded-lg shadow-md\">
    Unique layout
</div>

<!-- DO extract when repeated multiple times -->
<!-- Extract this as .card -->
<div class=\"bg-white p-6 rounded-lg shadow-md\"></div>
<div class=\"bg-white p-6 rounded-lg shadow-md\"></div>
<div class=\"bg-white p-6 rounded-lg shadow-md\"></div>

<!-- DO extract complex patterns with variants -->
<!-- Button with many states -->
.btn {
  @apply px-4 py-2 rounded transition;
  @apply hover:shadow-lg active:scale-95;
  @apply disabled:opacity-50 disabled:cursor-not-allowed;
}

<!-- DON'T extract just to extract -->
<!-- Keep utilities for one-off adjustments -->
<button class=\"btn mt-4\">Button with custom margin</button>

Template Component Extraction

Blade/Template Components
<!-- Better approach: Use template components -->
<!-- resources/views/components/button.blade.php -->
@props(['variant' => 'primary', 'size' => 'md'])

@php
$classes = 'inline-flex items-center justify-center font-medium rounded-lg transition';

$variants = [
    'primary' => 'bg-blue-600 text-white hover:bg-blue-700',
    'secondary' => 'bg-gray-200 text-gray-900 hover:bg-gray-300',
    'danger' => 'bg-red-600 text-white hover:bg-red-700',
];

$sizes = [
    'sm' => 'px-3 py-1 text-sm',
    'md' => 'px-4 py-2',
    'lg' => 'px-6 py-3 text-lg',
];

$classes .= ' ' . $variants[$variant] . ' ' . $sizes[$size];
@endphp

<button {{ $attributes->merge(['class' => $classes]) }}>
    {{ $slot }}
</button>

<!-- Usage -->
<x-button variant=\"primary\" size=\"lg\">
    Click Me
</x-button>

Practical Extraction Examples

Real-World Component Library
@layer components {
  /* Typography */
  .heading-1 {
    @apply text-4xl font-bold tracking-tight;
    @apply md:text-5xl lg:text-6xl;
  }

  .heading-2 {
    @apply text-3xl font-bold tracking-tight;
    @apply md:text-4xl;
  }

  .body-text {
    @apply text-base leading-relaxed text-gray-600;
    @apply dark:text-gray-300;
  }

  /* Layout */
  .section {
    @apply py-12 md:py-16 lg:py-20;
  }

  .container-fluid {
    @apply w-full px-4 sm:px-6 lg:px-8;
  }

  /* Components */
  .card-elevated {
    @apply bg-white dark:bg-gray-800;
    @apply rounded-xl shadow-lg;
    @apply hover:shadow-xl transition-shadow;
    @apply p-6;
  }

  .link {
    @apply text-blue-600 dark:text-blue-400;
    @apply hover:text-blue-700 dark:hover:text-blue-300;
    @apply underline transition-colors;
  }
}
Practice Tasks
  • Extract a button component with @apply that includes primary, secondary, and danger variants
  • Create a reusable card component using @layer components with header, body, and footer sections
  • Build a form input component with consistent styling, focus states, and error handling
  • Design a navigation link component that handles active state, hover effects, and dark mode

Key Takeaways

  • @apply directive: Compose utility classes into custom CSS classes
  • @layer directive: Organize custom styles into Tailwind's layers (base, components, utilities)
  • When to extract: Extract patterns repeated 3+ times or with complex variants
  • Template components: Prefer Blade/React/Vue components over CSS extraction when possible
  • Keep it simple: Don't over-abstract; inline utilities are often clearer
  • Maintenance: Extracted components are easier to update across your application

What's Next?

Next Topic: Continue to Customization to learn about configuring and extending Tailwind CSS.



Optimization & Performance

Optimize Tailwind CSS for production deployment

Understanding Optimization

Tailwind CSS generates thousands of utility classes. For production, it's crucial to remove unused styles to minimize file size. Tailwind's JIT (Just-in-Time) mode and content configuration make this process automatic and efficient.

Content Configuration

Configure Content Sources
// tailwind.config.js
module.exports = {
  content: [
    './resources/**/*.blade.php',
    './resources/**/*.js',
    './resources/**/*.vue',
    './app/**/*.php',
    './src/**/*.{html,js,jsx,ts,tsx}',
  ],
  // Tailwind will scan these files for class names
}

JIT Mode Benefits

Just-in-Time Compilation
// tailwind.config.js (v3+ uses JIT by default)
module.exports = {
  content: ['./src/**/*.{html,js}'],
  // JIT automatically enabled in v3+

  // Benefits:
  // ✅ Instant build times
  // ✅ All variants enabled by default
  // ✅ Arbitrary values work out of the box
  // ✅ Smaller CSS file size in development
  // ✅ No need for PurgeCSS configuration
}
<!-- JIT enables arbitrary values -->
<div class=\"top-[117px] w-[347px] bg-[#1da1f2]\">
  Custom values work automatically
</div>

<!-- All variants available -->
<div class=\"hover:scale-110 focus-within:ring-4 group-hover:opacity-100\">
  Any variant combination works
</div>

Production Build Process

Build Commands
// package.json
{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "watch": "vite build --watch"
  }
}
# Development build (unoptimized)
npm run dev

# Production build (optimized, minified)
npm run build

# Watch mode for development
npm run watch

CSS Minification

PostCSS Configuration
// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
    ...(process.env.NODE_ENV === 'production' ? {
      cssnano: {
        preset: ['default', {
          discardComments: {
            removeAll: true,
          },
        }]
      }
    } : {})
  }
}

Content Patterns

Advanced Content Configuration
// tailwind.config.js
module.exports = {
  content: {
    files: [
      './src/**/*.{html,js,jsx,ts,tsx}',
      './components/**/*.{vue,js}',
      './pages/**/*.{md,mdx}',
    ],
    // Extract classes from files manually
    extract: {
      // Extract from custom file types
      svelte: (content) => {
        return content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || []
      }
    },
    // Transform content before scanning
    transform: {
      md: (content) => {
        return remark().process(content)
      }
    }
  },
}

Safelist Important Classes

Prevent Class Removal
// tailwind.config.js
module.exports = {
  content: ['./src/**/*.{html,js}'],
  safelist: [
    'bg-red-500',
    'bg-green-500',
    'bg-blue-500',
    // Pattern-based safelisting
    {
      pattern: /bg-(red|green|blue)-(100|500|900)/,
    },
    // With variants
    {
      pattern: /bg-(red|green|blue)-(100|500|900)/,
      variants: ['hover', 'focus'],
    },
  ],
}

// Use when classes are generated dynamically:
// const color = dynamic ? 'red' : 'blue'
// className={`bg-${color}-500`} // Won't work without safelist

Analyzing Bundle Size

Size Analysis Tools
# Check final CSS size
ls -lh dist/css/app.css

# Detailed analysis
npm install -D @tailwindcss/cli
npx tailwindcss -o output.css --minify

# Compare sizes
du -h output.css
gzip -c output.css | wc -c  # Gzipped size

Dynamic Class Names (Warning)

Avoid String Concatenation
// ❌ BAD - Tailwind can't detect these
<div className={`text-${error ? 'red' : 'green'}-500`}></div>
<div className={`bg-${color}-500`}></div>

// ✅ GOOD - Full class names
<div className={error ? 'text-red-500' : 'text-green-500'}></div>

// ✅ GOOD - Use safelist for dynamic colors
const colorClasses = {
  red: 'bg-red-500',
  green: 'bg-green-500',
  blue: 'bg-blue-500',
}
<div className={colorClasses[color]}></div>

// ✅ GOOD - With clsx/classnames
import clsx from 'clsx'
<div className={clsx(
  'text-base',
  error && 'text-red-500',
  success && 'text-green-500'
)}></div>

CDN vs Build Process

Comparison
<!-- ❌ CDN (Not Recommended for Production) -->
<!-- File size: ~3MB (unoptimized) -->
<script src=\"https://cdn.tailwindcss.com\"></script>

<!-- Drawbacks: -->
<!-- - Large file size -->
<!-- - No purging -->
<!-- - No customization -->
<!-- - External dependency -->

<!-- ✅ Build Process (Recommended) -->
<!-- File size: 5-50KB (optimized) -->
<link href=\"/css/app.css\" rel=\"stylesheet\">

<!-- Benefits: -->
<!-- - Tiny file size -->
<!-- - Only used classes -->
<!-- - Full customization -->
<!-- - No external dependency -->

Layer Optimization

Organize for Better Performance
/* Optimize layer order */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Base: ~10KB (browser resets) */
/* Components: Your custom components */
/* Utilities: Only used utilities (~5-40KB) */

/* Heavy components in separate file */
@layer components {
  /* Critical components here */
}

/* Load non-critical styles separately */

Caching Strategies

Browser Caching
<!-- Use content hashing for long-term caching -->
<link rel=\"stylesheet\" href=\"/css/app.8f7a2d3e.css\">

<!-- Vite/Webpack automatically adds hash -->

<!-- HTTP Headers (nginx example) -->
<!-- location ~* \.css$ { -->
<!--   expires 1y; -->
<!--   add_header Cache-Control \"public, immutable\"; -->
<!-- } -->

Split CSS by Route

Code Splitting
// vite.config.js or webpack config
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'tailwind-base': ['./src/styles/base.css'],
          'components': ['./src/styles/components.css'],
        }
      }
    }
  }
}

// Load critical CSS inline
<style>
  /* Critical above-the-fold styles */
  .hero { /* ... */ }
</style>

// Load rest async
<link rel=\"preload\" href=\"/css/app.css\" as=\"style\">
<link rel=\"stylesheet\" href=\"/css/app.css\" media=\"print\" onload=\"this.media='all'\">

Performance Checklist

Optimization Steps
# 1. Configure content paths correctly
# ✅ All template files included
# ✅ No unnecessary paths

# 2. Use JIT mode (default in v3+)
# ✅ Fast builds
# ✅ Automatic purging

# 3. Minify for production
# ✅ PostCSS with cssnano
# ✅ Remove comments

# 4. Enable gzip/brotli compression
# ✅ Server-side compression
# ✅ 70-80% size reduction

# 5. Use content hashing
# ✅ Long-term caching
# ✅ Cache busting

# 6. Analyze bundle
# npm run build
# Check final size: ls -lh dist/css/

# Target sizes:
# Small site: 5-15KB
# Medium site: 15-40KB
# Large site: 40-100KB

Performance Metrics

Before & After Optimization
Before Optimization (CDN):
- File size: 3.8MB
- Gzipped: 350KB
- Load time: 1.2s (3G)
- FCP: 2.5s

After Optimization (Build):
- File size: 28KB
- Gzipped: 5.2KB
- Load time: 0.08s (3G)
- FCP: 0.9s

Optimization Gains:
- 99.3% size reduction
- 98.5% gzipped reduction
- 15x faster load time
- 2.8x faster FCP
Practice Tasks
  • Configure content paths for your project and verify all templates are included
  • Create a production build and analyze the final CSS file size
  • Implement safelist for dynamically generated color classes
  • Set up gzip compression and compare before/after sizes

Key Takeaways

  • JIT mode: Default in v3+, enables fast builds and automatic purging
  • Content config: Critical for detecting used classes
  • Avoid concatenation: Write full class names for proper detection
  • Production builds: Always minify and compress for production
  • Target size: Aim for under 50KB for most projects
  • Monitor performance: Regularly check bundle size and load times

What's Next?

Next Topic: Continue to Best Practices to learn about Tailwind CSS best practices and conventions.

Best Practices

Write maintainable and scalable Tailwind CSS code

Understanding Best Practices

Following best practices ensures your Tailwind CSS codebase remains maintainable, scalable, and easy to understand. These guidelines help teams work efficiently and avoid common pitfalls.

Class Organization

Logical Class Ordering
<!-- ❌ Unorganized -->
<div class=\"text-white hover:bg-blue-600 p-4 bg-blue-500 rounded flex items-center\">

<!-- ✅ Organized by category -->
<div class=\"
  flex items-center
  p-4 rounded
  bg-blue-500 hover:bg-blue-600
  text-white
\">

<!-- Recommended order: -->
<!-- 1. Layout (flex, grid, display) -->
<!-- 2. Positioning (absolute, relative) -->
<!-- 3. Sizing (w-, h-, min-, max-) -->
<!-- 4. Spacing (p-, m-, space-) -->
<!-- 5. Typography (font-, text-, leading-) -->
<!-- 6. Visual (bg-, border-, shadow-) -->
<!-- 7. Effects (opacity-, transform-) -->
<!-- 8. Transitions (transition-, duration-) -->
<!-- 9. Interactivity (cursor-, pointer-events-) -->
<!-- 10. Variants (hover:, focus:, etc.) -->

When to Extract Components

Component Extraction Guidelines
<!-- ❌ Don't extract single-use patterns -->
.page-header {
  @apply text-3xl font-bold text-gray-900;
}
<!-- Just 3 classes, not worth extracting -->

<!-- ✅ Extract repeated complex patterns -->
@layer components {
  .btn {
    @apply inline-flex items-center justify-center;
    @apply px-4 py-2 border border-transparent;
    @apply text-sm font-medium rounded-md;
    @apply focus:outline-none focus:ring-2 focus:ring-offset-2;
    @apply transition-colors duration-200;
  }
}

<!-- Guidelines: -->
<!-- - Extract if used 3+ times -->
<!-- - Extract if 8+ utilities -->
<!-- - Extract for component library -->
<!-- - Keep simple patterns inline -->

Naming Conventions

Consistent Component Names
@layer components {
  /* ✅ Use descriptive, hierarchical names */
  .btn { /* base button */ }
  .btn-primary { /* primary variant */ }
  .btn-lg { /* size modifier */ }

  .card { /* base card */ }
  .card-header { /* card subcomponent */ }
  .card-body { /* card subcomponent */ }
  .card-footer { /* card subcomponent */ }

  /* ✅ BEM-style for complex components */
  .alert { /* block */ }
  .alert__icon { /* element */ }
  .alert--success { /* modifier */ }

  /* ❌ Avoid generic names */
  .container { /* conflicts with Tailwind */ }
  .wrapper { /* too generic */ }
  .box { /* unclear purpose */ }
}

Responsive Design Patterns

Mobile-First Approach
<!-- ✅ Mobile-first (recommended) -->
<div class=\"
  text-sm md:text-base lg:text-lg
  p-4 md:p-6 lg:p-8
  grid-cols-1 md:grid-cols-2 lg:grid-cols-3
\">
  <!-- Start with mobile, enhance for larger screens -->
</div>

<!-- ❌ Desktop-first -->
<div class=\"
  text-lg md:text-base sm:text-sm
  p-8 md:p-6 sm:p-4
\">
  <!-- Harder to maintain, goes against Tailwind's philosophy -->
</div>

<!-- ✅ Hide/show by breakpoint -->
<div class=\"block md:hidden\">Mobile menu</div>
<div class=\"hidden md:block\">Desktop menu</div>

Avoiding Specificity Wars

Layer Management
/* ✅ Use layers properly */
@layer base {
  h1 { @apply text-4xl font-bold; }
}

@layer components {
  .btn { @apply px-4 py-2; }
}

@layer utilities {
  .text-shadow { text-shadow: 2px 2px 4px rgba(0,0,0,0.1); }
}

/* ❌ Don't fight specificity */
.btn.btn { /* Bad: doubling classes */
  @apply px-4 py-2 !important; /* Worse: using !important */
}

/* ✅ Use Tailwind's important */
/* tailwind.config.js */
module.exports = {
  important: '#app', /* Scope to container */
}

Configuration Organization

Well-Structured Config
// ✅ Organized tailwind.config.js
module.exports = {
  content: [
    './src/**/*.{html,js,jsx,ts,tsx}',
  ],

  darkMode: 'class',

  theme: {
    // Override core theme
    screens: {
      sm: '640px',
      md: '768px',
      lg: '1024px',
      xl: '1280px',
    },

    extend: {
      // Add to default theme
      colors: {
        brand: {
          50: '#eff6ff',
          // ... other shades
          900: '#1e3a8a',
        },
      },

      fontFamily: {
        sans: ['Inter', 'sans-serif'],
      },

      spacing: {
        '128': '32rem',
      },
    },
  },

  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/typography'),
  ],
}

Team Guidelines

Team Conventions
<!-- Establish team standards -->

<!-- 1. Formatting: Use Prettier with plugin -->
{
  "plugins": ["prettier-plugin-tailwindcss"]
}

<!-- 2. Class limits: Max ~10-15 utilities inline -->
<div class=\"flex items-center gap-4 px-6 py-3 bg-white rounded-lg shadow\">
  <!-- Acceptable inline -->
</div>

<!-- 3. Extract when repeated 3+ times -->
@layer components {
  .card-base {
    @apply bg-white rounded-lg shadow-md p-6;
  }
}

<!-- 4. Document custom utilities -->
@layer utilities {
  /* Adds text shadow for better readability on images */
  .text-shadow {
    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
  }
}

<!-- 5. Use consistent spacing scale -->
<!-- Stick to 4, 8, 12, 16, 24, 32, 48, 64 (px) -->
<div class=\"p-4 space-y-4\">
  <div class=\"mb-8\">...</div>
</div>

Accessibility Best Practices

Accessible Components
<!-- ✅ Include focus styles -->
<button class=\"
  bg-blue-500 text-white px-4 py-2 rounded
  hover:bg-blue-600
  focus:outline-none focus:ring-2 focus:ring-blue-300 focus:ring-offset-2
  disabled:opacity-50 disabled:cursor-not-allowed
\">
  Click me
</button>

<!-- ✅ Sufficient color contrast -->
<div class=\"bg-gray-900 text-white\">
  <!-- Good contrast ratio -->
</div>

<!-- ❌ Poor contrast -->
<div class=\"bg-gray-300 text-gray-400\">
  <!-- Fails WCAG guidelines -->
</div>

<!-- ✅ Visible focus indicators -->
<input class=\"
  border border-gray-300 rounded px-3 py-2
  focus:border-blue-500 focus:ring-2 focus:ring-blue-200
\" />

<!-- ✅ Screen reader support -->
<button class=\"p-2\" aria-label=\"Close menu\">
  <svg class=\"w-6 h-6\">...</svg>
</button>

Performance Patterns

Efficient Class Usage
<!-- ❌ Redundant classes -->
<div class=\"flex flex-row\">
  <!-- flex-row is default, remove it -->
</div>

<!-- ✅ Minimal necessary classes -->
<div class=\"flex\">
  <!-- flex-row is default -->
</div>

<!-- ❌ Conflicting classes -->
<div class=\"p-4 px-8\">
  <!-- px-8 overrides p-4's horizontal padding -->
</div>

<!-- ✅ Clear intent -->
<div class=\"py-4 px-8\">
  <!-- Explicitly set vertical and horizontal -->
</div>

<!-- ✅ Avoid arbitrary values when utilities exist -->
<div class=\"w-64\"></div>  <!-- Good -->
<div class=\"w-[256px]\"></div>  <!-- Less ideal -->

Dark Mode Patterns

Consistent Dark Mode
<!-- ✅ Systematic dark mode classes -->
<div class=\"
  bg-white dark:bg-gray-900
  text-gray-900 dark:text-gray-100
  border-gray-200 dark:border-gray-700
\">
  <!-- Consistent light/dark pairs -->
</div>

<!-- ✅ Extract dark mode components -->
@layer components {
  .card {
    @apply bg-white dark:bg-gray-800;
    @apply text-gray-900 dark:text-gray-100;
    @apply border border-gray-200 dark:border-gray-700;
  }
}

<!-- ✅ Use CSS variables for complex themes -->
:root {
  --color-primary: #3b82f6;
  --color-background: #ffffff;
}

.dark {
  --color-primary: #60a5fa;
  --color-background: #1f2937;
}

<div class=\"bg-[var(--color-background)]\">...</div>

Documentation Practices

Document Custom Utilities
@layer utilities {
  /**
   * Text shadow utilities
   * Usage: text-shadow, text-shadow-md, text-shadow-lg
   * Good for text over images
   */
  .text-shadow {
    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
  }

  /**
   * Content visibility utilities
   * Improves rendering performance for off-screen content
   * Usage: content-auto, content-hidden
   */
  .content-auto {
    content-visibility: auto;
  }
}

@layer components {
  /**
   * Alert component system
   * Variants: alert-success, alert-error, alert-warning, alert-info
   * Usage: 
Success message
*/ .alert { @apply p-4 rounded-md border; } }

Testing Utilities

Test-Friendly Classes
<!-- ✅ Add data attributes for testing -->
<button
  data-testid=\"submit-button\"
  class=\"bg-blue-500 hover:bg-blue-600 px-4 py-2 rounded\"
>
  Submit
</button>

<!-- ✅ Use semantic HTML + Tailwind -->
<nav aria-label=\"Main navigation\" class=\"flex gap-4\">
  <a href=\"#\" class=\"text-blue-600 hover:text-blue-800\">Home</a>
</nav>

<!-- Don't rely on classes for test selectors -->
<!-- Classes change, use data-testid or aria labels -->

Version Control

Git Best Practices
# .gitignore
node_modules/
dist/
build/
*.log

# Commit generated config (if using custom build)
# tailwind.config.js ✅ commit
# postcss.config.js ✅ commit
# package.json ✅ commit
# package-lock.json ✅ commit

# Don't commit
# node_modules/ ❌
# dist/ ❌
# .cache/ ❌

Common Anti-Patterns

What to Avoid
<!-- ❌ String concatenation -->
<div className={`text-${color}-500`}></div>

<!-- ❌ Inline styles with Tailwind -->
<div class=\"p-4\" style=\"padding: 20px;\"></div>

<!-- ❌ !important everywhere -->
.custom { @apply p-4 !important; }

<!-- ❌ Overriding Tailwind core -->
.flex { display: block !important; }

<!-- ❌ Mixing frameworks -->
<div class=\"p-4 bootstrap-class\"></div>

<!-- ❌ Too many arbitrary values -->
<div class=\"w-[347px] h-[239px] mt-[17px]\">
  <!-- Add to config instead -->
</div>
Practice Tasks
  • Organize your classes using the recommended order (layout, spacing, visual, etc.)
  • Review your codebase and extract components that are used 3+ times
  • Add focus styles to all interactive elements for accessibility
  • Document your custom utilities and components with comments

Key Takeaways

  • Organize classes: Follow consistent order for better readability
  • Extract wisely: Only extract components used 3+ times or with 8+ utilities
  • Mobile-first: Start with mobile styles, enhance for larger screens
  • Accessibility: Always include focus styles and proper contrast
  • Document custom code: Add comments for custom utilities and components
  • Team consistency: Establish and follow team conventions

What's Next?

Next Topic: Continue to Migration to learn about upgrading Tailwind versions.

Migration & Upgrades

Upgrade Tailwind CSS versions and migrate legacy code

Understanding Migration

Tailwind CSS evolves with each version, introducing new features and occasionally breaking changes. Understanding migration paths helps you upgrade smoothly while taking advantage of new capabilities and performance improvements.

Checking Current Version

Version Detection
# Check installed version
npm list tailwindcss

# Check latest version
npm show tailwindcss version

# View package.json
cat package.json | grep tailwindcss

# Output example:
# tailwindcss@3.4.1

Upgrading to v3.x

Version 3 Upgrade Process
# 1. Update Tailwind CSS
npm install -D tailwindcss@latest

# 2. Update PostCSS and Autoprefixer
npm install -D postcss@latest autoprefixer@latest

# 3. Update official plugins
npm install -D @tailwindcss/forms@@latest
npm install -D @tailwindcss/typography@@latest

# 4. Run build to check for issues
npm run build

v2 to v3 Breaking Changes

Major Changes from v2
// ❌ v2 Configuration
module.exports = {
  purge: ['./src/**/*.html'],
  mode: 'jit',
  darkMode: false,
  // ...
}

// ✅ v3 Configuration
module.exports = {
  content: ['./src/**/*.html'], // Changed from 'purge'
  // JIT is always enabled, remove 'mode'
  darkMode: 'media', // or 'class'
  // ...
}

// Key Changes:
// 1. 'purge' → 'content'
// 2. JIT mode always enabled (remove 'mode')
// 3. New color palette (gray-50 to gray-950)
// 4. Play CDN for development only

Color Palette Changes

v2 vs v3 Colors
<!-- v2 Colors -->
<div class=\"bg-gray-50\"></div>  <!-- lightest -->
<div class=\"bg-gray-900\"></div> <!-- darkest -->

<!-- v3 Colors (extended range) -->
<div class=\"bg-gray-50\"></div>   <!-- lightest -->
<div class=\"bg-gray-950\"></div>  <!-- NEW: even darker -->

<!-- Removed in v3: -->
<!-- - lightBlue → sky -->
<!-- - warmGray, trueGray, coolGray → gray -->
<!-- - amber, emerald, fuchsia added -->

<!-- Migration: -->
<div class=\"bg-lightBlue-500\"></div>  <!-- v2 -->
<div class=\"bg-sky-500\"></div>       <!-- v3 -->

Legacy Class Replacements

Deprecated Classes
<!-- v2: overflow-clip-margin -->
<div class=\"overflow-clip-margin-4\"></div>
<!-- v3: Not available, use custom CSS -->

<!-- v2: decoration-slice/clone -->
<span class=\"decoration-clone\"></span>
<!-- v3: box-decoration-slice/clone -->
<span class=\"box-decoration-clone\"></span>

<!-- v2: flex-grow/shrink -->
<div class=\"flex-grow\"></div>
<!-- v3: grow/shrink (shorter) -->
<div class=\"grow\"></div>

<!-- v2: transform classes -->
<div class=\"transform scale-50 rotate-45\"></div>
<!-- v3: 'transform' not needed -->
<div class=\"scale-50 rotate-45\"></div>

JIT Migration Benefits

JIT Mode Features
<!-- v2 (Classic Mode): Limited variants -->
<!-- Need to enable variants in config -->

<!-- v3 (Always JIT): All variants available -->
<div class=\"
  hover:scale-110
  focus:ring-4
  active:scale-95
  group-hover:opacity-100
  peer-checked:bg-blue-500
  first:mt-0
  last:mb-0
  odd:bg-gray-50
  even:bg-white
\">
  All variants work automatically!
</div>

<!-- Arbitrary values (v3 JIT) -->
<div class=\"top-[117px]\"></div>
<div class=\"bg-[#1da1f2]\"></div>
<div class=\"grid-cols-[200px_1fr_100px]\"></div>

Plugin Migration

Updating Plugins
// v2 Plugin Syntax
module.exports = {
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/typography'),
    require('@tailwindcss/aspect-ratio'),
  ],
}

// v3 Plugin Syntax (same, but update versions)
module.exports = {
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/typography'),
    // aspect-ratio now built-in, can remove
  ],
}

// Update plugin versions
npm install -D @tailwindcss/forms@@latest
npm install -D @tailwindcss/typography@@latest

Custom Plugin Updates

Plugin API Changes
// v2 Plugin
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities, variants }) {
      const utilities = {
        '.content-auto': { contentVisibility: 'auto' },
      }
      addUtilities(utilities, variants('contentVisibility'))
    })
  ]
}

// v3 Plugin (simpler)
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities }) {
      const utilities = {
        '.content-auto': { contentVisibility: 'auto' },
      }
      // All variants automatically available in v3
      addUtilities(utilities)
    })
  ]
}

Migrating from CDN to Build

From CDN to Build Process
<!-- OLD: CDN (Development only) -->
<script src=\"https://cdn.tailwindcss.com\"></script>

<!-- NEW: Build Process -->
<!-- 1. Install Tailwind -->
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
// 2. Configure tailwind.config.js
module.exports = {
  content: ['./src/**/*.{html,js}'],
  theme: {
    extend: {},
  },
  plugins: [],
}
/* 3. Create CSS file (src/input.css) */
@tailwind base;
@tailwind components;
@tailwind utilities;
// 4. Add build script to package.json
{
  "scripts": {
    "build": "tailwindcss -i ./src/input.css -o ./dist/output.css",
    "watch": "tailwindcss -i ./src/input.css -o ./dist/output.css --watch"
  }
}
<!-- 5. Link built CSS -->
<link href=\"/dist/output.css\" rel=\"stylesheet\">

Configuration File Changes

Config Updates
// v2 Config
module.exports = {
  purge: {
    content: ['./src/**/*.html'],
    options: {
      safelist: ['bg-red-500'],
    }
  },
  mode: 'jit',
  darkMode: false,
  theme: {
    extend: {},
  },
  variants: {
    extend: {
      backgroundColor: ['active'],
    }
  },
  plugins: [],
}

// v3 Config (simplified)
module.exports = {
  content: ['./src/**/*.html'],
  // No 'mode', JIT is default
  darkMode: 'class',
  safelist: ['bg-red-500'], // Moved to root level
  theme: {
    extend: {},
  },
  // No 'variants', all variants available
  plugins: [],
}

Testing After Migration

Verification Checklist
# 1. Clean install
rm -rf node_modules package-lock.json
npm install

# 2. Build and check for errors
npm run build

# 3. Check file size (should be smaller in v3)
ls -lh dist/css/app.css

# 4. Test in development
npm run dev

# 5. Visual regression testing
# - Check all pages
# - Verify colors match
# - Test responsive breakpoints
# - Test dark mode (if used)
# - Verify hover/focus states

# 6. Browser testing
# - Chrome
# - Firefox
# - Safari
# - Edge

Common Migration Issues

Troubleshooting
// Issue: Classes not being generated
// Solution: Check content configuration
module.exports = {
  content: [
    './src/**/*.{html,js,jsx,ts,tsx}', // ✅ Correct patterns
    './components/**/*.vue',
  ],
}

// Issue: Colors look different
// Solution: Update to new color names
// lightBlue → sky
// warmGray → gray
// coolGray → gray

// Issue: Variants not working
// Solution: Ensure using v3+, all variants work automatically

// Issue: Custom plugin errors
// Solution: Update plugin API (remove variants parameter)

// Issue: Large file size
// Solution: Verify content paths, enable minification

Gradual Migration Strategy

Step-by-Step Approach
# Phase 1: Preparation (Week 1)
# - Create feature branch
# - Backup current version
# - Review changelog
# - Identify breaking changes

# Phase 2: Update Dependencies (Week 2)
npm install -D tailwindcss@@latest
npm install -D @tailwindcss/forms@@latest

# Phase 3: Update Configuration (Week 2)
# - Rename 'purge' to 'content'
# - Remove 'mode: jit'
# - Update color names
# - Remove 'variants' section

# Phase 4: Update Code (Week 3-4)
# - Replace deprecated classes
# - Update color names
# - Remove unnecessary 'transform' classes
# - Test each component

# Phase 5: Testing (Week 5)
# - Visual regression testing
# - Cross-browser testing
# - Performance testing
# - Accessibility testing

# Phase 6: Deploy (Week 6)
# - Deploy to staging
# - Final testing
# - Deploy to production
# - Monitor for issues

Automation Tools

Migration Scripts
// Install codemod tool
npm install -g @tailwindcss/upgrade

// Run automatic migration
npx @tailwindcss/upgrade

// Manual find/replace patterns:
// Find: class=\"flex-grow
// Replace: class=\"grow

// Find: class=\"flex-shrink
// Replace: class=\"shrink

// Find: bg-lightBlue-
// Replace: bg-sky-

// Find: overflow-ellipsis
// Replace: text-ellipsis

Future-Proofing

Best Practices for Upgrades
// 1. Pin versions in package.json (initially)
{
  "dependencies": {
    "tailwindcss": "3.4.1" // Specific version
  }
}

// 2. Use ^ for minor updates later
{
  "dependencies": {
    "tailwindcss": "^3.4.0" // Allow patches
  }
}

// 3. Keep dependencies updated
npm outdated
npm update

// 4. Read changelogs
// Visit: https://github.com/tailwindlabs/tailwindcss/releases

// 5. Test before upgrading
// - Create test branch
// - Run full test suite
// - Visual regression tests

// 6. Document custom code
// - Comment complex utilities
// - Maintain changelog
// - Document breaking changes
Practice Tasks
  • Check your current Tailwind version and compare with latest release
  • Create a test branch and upgrade Tailwind to the latest version
  • Update deprecated class names (flex-grow → grow, etc.)
  • Test your application thoroughly after migration

Key Takeaways

  • v3 changes: 'purge' → 'content', JIT always enabled, new colors
  • Test thoroughly: Visual regression and cross-browser testing essential
  • Gradual migration: Use phased approach for large projects
  • Read changelogs: Always review release notes before upgrading
  • Automate when possible: Use codemods and scripts for repetitive changes
  • Stay updated: Regular minor updates easier than major version jumps

What's Next?

Congratulations! You've completed the Tailwind CSS learning path. Continue practicing and building projects to master these concepts. Check the official documentation for the latest updates.

Last updated: February 2026