Available for day contractsFrom 21st September I have availability for day and half day contracts. Please contact for more information.

Contact →
mikepreston.org

Tailwind CSS

A utility-first CSS framework for rapidly building custom user interfaces without writing custom CSS.

Tailwind CSS Cheatsheet

A utility-first CSS framework for rapidly building custom user interfaces without writing custom CSS.

Overview

Version note: this sheet covers Tailwind CSS v3.x (verified against v3.4.x). Tailwind v4 (released January 2025) is a ground-up rewrite with CSS-first configuration — @import "tailwindcss"; replaces the @tailwind directives, theme tokens move into @theme { … } in CSS, there is no tailwind.config.js by default, and custom utilities/variants use @utility/@variant. To follow this sheet, pin tailwindcss@3; for new projects, see the Tailwind CSS v4 sheet.

Tailwind CSS provides low-level utility classes that let you build completely custom designs without ever leaving your HTML. Instead of pre-designed components, you compose utilities to create any design directly in your markup.

Build ProcessSource FilesJIT EngineUnused CSS RemovalOptimised CSSUtility CompositionBase StylesComponent ClassesUtility ClassesTailwind CSS ArchitectureHTML with UtilityClassesTailwind Compilertailwind.config.jsGenerated CSSBuild ProcessSource FilesJIT EngineUnused CSS RemovalOptimised CSSUtility CompositionBase StylesComponent ClassesUtility ClassesTailwind CSS ArchitectureHTML with UtilityClassesTailwind Compilertailwind.config.jsGenerated CSS

Utility-First Concepts

Key Concepts

Concept Description
Utility Classes Single-purpose classes that do one thing well
Composition Combining multiple utilities to build complex designs
Design Tokens Consistent spacing, colours, and typography scales
Responsive Prefixes Mobile-first breakpoint modifiers
State Variants Hover, focus, active, and other state modifiers
Arbitrary Values Custom values using square bracket notation

Common Patterns

<!-- Traditional CSS approach -->
<div class="chat-notification">
  <p class="chat-notification-message">You have a new message!</p>
</div>

<!-- Tailwind utility-first approach -->
<div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-lg flex items-center space-x-4">
  <div>
    <div class="text-xl font-medium text-black">ChitChat</div>
    <p class="text-slate-500">You have a new message!</p>
  </div>
</div>

Examples

<!-- Button with utility classes -->
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Click me
</button>

<!-- Card component -->
<div class="bg-white shadow-md rounded-lg p-6 max-w-md">
  <h2 class="text-2xl font-bold mb-2">Card Title</h2>
  <p class="text-gray-700">Card content goes here.</p>
</div>

<!-- Using arbitrary values -->
<div class="top-[117px] bg-[#1da1f2] w-[calc(100%-2rem)]">
  Custom values without configuration
</div>

Common Utilities

Spacing (Margin and Padding)

Class Pattern Description Example
m-{size} Margin all sides m-4 (1rem)
mx-{size} Margin horizontal mx-auto (centre)
my-{size} Margin vertical my-2 (0.5rem)
mt/mr/mb/ml-{size} Margin single side mt-8 (2rem)
p-{size} Padding all sides p-4 (1rem)
px-{size} Padding horizontal px-6 (1.5rem)
py-{size} Padding vertical py-3 (0.75rem)
pt/pr/pb/pl-{size} Padding single side pl-4 (1rem)
space-x-{size} Horizontal space between children space-x-4
space-y-{size} Vertical space between children space-y-2

Spacing Scale:

  • 0 = 0px
  • 1 = 0.25rem (4px)
  • 2 = 0.5rem (8px)
  • 4 = 1rem (16px)
  • 8 = 2rem (32px)
  • 16 = 4rem (64px)

Colours

<!-- Text colours -->
<p class="text-red-500">Red text</p>
<p class="text-blue-600">Blue text</p>
<p class="text-gray-900">Dark gray text</p>

<!-- Background colours -->
<div class="bg-green-200">Light green background</div>
<div class="bg-purple-500">Purple background</div>

<!-- Border colours -->
<div class="border-2 border-yellow-400">Yellow border</div>

<!-- Opacity variants -->
<div class="bg-black/50">50% opacity black</div>
<div class="text-white/75">75% opacity white text</div>

Colour Scale: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950

Typography

Class Description
text-xs/sm/base/lg/xl/2xl Font size
font-thin/light/normal/medium/semibold/bold Font weight
italic / not-italic Font style
tracking-tight/normal/wide Letter spacing
leading-none/tight/normal/relaxed/loose Line height
text-left/center/right/justify Text alignment
uppercase/lowercase/capitalize Text transform
underline/line-through/no-underline Text decoration
truncate Truncate with ellipsis
whitespace-nowrap/pre/pre-line Whitespace handling
<!-- Typography examples -->
<h1 class="text-4xl font-bold tracking-tight">Main Heading</h1>
<p class="text-base leading-relaxed text-gray-600">
  Body text with relaxed line height
</p>
<span class="text-sm font-medium uppercase tracking-wide">
  Label Text
</span>

Sizing

<!-- Width -->
<div class="w-full">Full width</div>
<div class="w-1/2">50% width</div>
<div class="w-64">16rem width</div>
<div class="w-screen">Viewport width</div>
<div class="max-w-md">Max width medium</div>
<div class="min-w-0">Min width 0</div>

<!-- Height -->
<div class="h-screen">Viewport height</div>
<div class="h-full">100% height</div>
<div class="h-64">16rem height</div>
<div class="min-h-screen">Minimum viewport height</div>

Responsive Design

Key Concepts

Tailwind uses a mobile-first breakpoint system. Unprefixed utilities target all screen sizes, while prefixed utilities only apply at the specified breakpoint and above.

Mobile First ApproachMobileDefaultsm:640px+md:768px+lg:1024px+xl:1280px+2xl:1536px+Mobile First ApproachMobileDefaultsm:640px+md:768px+lg:1024px+xl:1280px+2xl:1536px+

Breakpoint Prefixes

Prefix Minimum Width CSS
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)

Examples

<!-- Responsive width -->
<div class="w-full md:w-1/2 lg:w-1/3">
  Full width on mobile, half on tablet, third on desktop
</div>

<!-- Responsive text size -->
<h1 class="text-2xl sm:text-3xl md:text-4xl lg:text-5xl">
  Responsive heading
</h1>

<!-- Responsive padding -->
<div class="p-4 md:p-6 lg:p-8">
  Increasing padding on larger screens
</div>

<!-- Responsive layout -->
<div class="flex flex-col md:flex-row">
  <div class="w-full md:w-1/3">Sidebar</div>
  <div class="w-full md:w-2/3">Main content</div>
</div>

<!-- Hide/show at breakpoints -->
<div class="hidden md:block">Visible on md and above</div>
<div class="md:hidden">Visible only below md</div>

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

Flexbox and Grid Utilities

Flexbox

<!-- Flex container -->
<div class="flex">Flex container</div>
<div class="inline-flex">Inline flex</div>

<!-- Direction -->
<div class="flex flex-row">Horizontal (default)</div>
<div class="flex flex-col">Vertical</div>
<div class="flex flex-row-reverse">Reversed horizontal</div>

<!-- Justify content (main axis) -->
<div class="flex justify-start">Start</div>
<div class="flex justify-center">Centre</div>
<div class="flex justify-end">End</div>
<div class="flex justify-between">Space between</div>
<div class="flex justify-around">Space around</div>
<div class="flex justify-evenly">Space evenly</div>

<!-- Align items (cross axis) -->
<div class="flex items-start">Top</div>
<div class="flex items-center">Centre</div>
<div class="flex items-end">Bottom</div>
<div class="flex items-stretch">Stretch (default)</div>
<div class="flex items-baseline">Baseline</div>

<!-- Flex wrap -->
<div class="flex flex-wrap">Wrap</div>
<div class="flex flex-nowrap">No wrap</div>

<!-- Gap -->
<div class="flex gap-4">Gap all sides</div>
<div class="flex gap-x-4">Horizontal gap</div>
<div class="flex gap-y-2">Vertical gap</div>

<!-- Flex children -->
<div class="flex-1">Grow and shrink</div>
<div class="flex-none">Don't grow or shrink</div>
<div class="flex-auto">Grow based on content</div>
<div class="grow">Grow</div>
<div class="shrink-0">Don't shrink</div>

Grid

<!-- Grid container -->
<div class="grid grid-cols-3">Three columns</div>
<div class="grid grid-cols-12">Twelve column grid</div>

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

<!-- Column span -->
<div class="col-span-2">Span 2 columns</div>
<div class="col-span-full">Span all columns</div>

<!-- Row span -->
<div class="row-span-2">Span 2 rows</div>

<!-- Grid rows -->
<div class="grid grid-rows-3">Three rows</div>

<!-- Auto-fit/auto-fill with arbitrary values -->
<div class="grid grid-cols-[repeat(auto-fit,minmax(200px,1fr))]">
  Auto-fit columns
</div>

<!-- Place items -->
<div class="grid place-items-center">Centre all items</div>
<div class="grid place-content-center">Centre content</div>

<!-- Grid template areas (with arbitrary values) -->
<div class="grid grid-cols-[1fr_2fr] grid-rows-[auto_1fr_auto]">
  Custom grid template
</div>

Flexbox vs Grid Decision Flow

One-dimensionalTwo-dimensionalNavigationCentringCard layoutEqual columnsComplex layoutAuto-fitLayout DecisionOne-dimensionalor two-dimensional?Use FlexboxUse GridMain use case?flex justify-betweenflex items-centerjustify-centerflex flex-wrap gap-4Layout type?grid grid-cols-3grid with spansauto-fit/minmaxOne-dimensionalTwo-dimensionalNavigationCentringCard layoutEqual columnsComplex layoutAuto-fitLayout DecisionOne-dimensionalor two-dimensional?Use FlexboxUse GridMain use case?flex justify-betweenflex items-centerjustify-centerflex flex-wrap gap-4Layout type?grid grid-cols-3grid with spansauto-fit/minmax

Customisation

tailwind.config.js

// tailwind.config.js
module.exports = {
  // Content sources for class detection
  content: [
    './src/**/*.{html,js,jsx,ts,tsx}',
    './public/index.html',
  ],

  // Dark mode strategy
  darkMode: 'class', // or 'media'

  theme: {
    // Override default theme
    screens: {
      'sm': '640px',
      'md': '768px',
      'lg': '1024px',
      'xl': '1280px',
      '2xl': '1536px',
    },

    // Extend default theme
    extend: {
      // Custom colours
      colors: {
        'brand': {
          50: '#f0f9ff',
          100: '#e0f2fe',
          500: '#0ea5e9',
          900: '#0c4a6e',
        },
        'primary': '#3490dc',
        'secondary': '#ffed4a',
        'danger': '#e3342f',
      },

      // Custom spacing
      spacing: {
        '72': '18rem',
        '84': '21rem',
        '96': '24rem',
        '128': '32rem',
      },

      // Custom fonts
      fontFamily: {
        'sans': ['Inter', 'sans-serif'],
        'serif': ['Merriweather', 'serif'],
        'mono': ['Fira Code', 'monospace'],
      },

      // Custom breakpoints
      screens: {
        '3xl': '1920px',
      },

      // Custom animations
      animation: {
        'spin-slow': 'spin 3s linear infinite',
        'bounce-slow': 'bounce 2s infinite',
      },

      // Border radius
      borderRadius: {
        '4xl': '2rem',
      },
    },
  },

  // Plugins
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/typography'),
    require('@tailwindcss/aspect-ratio'),
  ],
}

Using Custom Values

<!-- Using custom colours -->
<div class="bg-brand-500 text-brand-50">
  Custom brand colours
</div>

<!-- Using custom spacing -->
<div class="p-72 mt-128">
  Custom spacing values
</div>

<!-- Using custom fonts -->
<p class="font-serif">
  Custom serif font
</p>

@apply Directive

/* styles.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .btn {
    @apply px-4 py-2 rounded font-semibold;
  }

  .btn-primary {
    @apply btn bg-blue-500 text-white hover:bg-blue-600;
  }

  .btn-secondary {
    @apply btn bg-gray-200 text-gray-800 hover:bg-gray-300;
  }

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

  .input {
    @apply border border-gray-300 rounded px-3 py-2
           focus:outline-none focus:ring-2 focus:ring-blue-500;
  }
}

Component Patterns

Common UI Components

<!-- Button variants -->
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Primary
</button>
<button class="bg-transparent hover:bg-blue-500 text-blue-700 font-semibold
               hover:text-white py-2 px-4 border border-blue-500
               hover:border-transparent rounded">
  Outline
</button>

<!-- Card -->
<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">Card description</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">
      #tag
    </span>
  </div>
</div>

<!-- Alert -->
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded" role="alert">
  <strong class="font-bold">Error!</strong>
  <span class="block sm:inline">Something went wrong.</span>
</div>

<!-- Form input -->
<div class="mb-4">
  <label class="block text-gray-700 text-sm font-bold mb-2" for="username">
    Username
  </label>
  <input class="shadow appearance-none border rounded w-full py-2 px-3
                text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
         id="username" type="text" placeholder="Username">
</div>

<!-- Navigation -->
<nav class="flex items-center justify-between flex-wrap bg-teal-500 p-6">
  <div class="flex items-center flex-shrink-0 text-white mr-6">
    <span class="font-semibold text-xl tracking-tight">Brand</span>
  </div>
  <div class="w-full block flex-grow lg:flex lg:items-center lg:w-auto">
    <div class="text-sm lg:flex-grow">
      <a href="#" class="block mt-4 lg:inline-block lg:mt-0 text-teal-200
                        hover:text-white mr-4">
        Link
      </a>
    </div>
  </div>
</nav>

<!-- Badge -->
<span class="inline-flex items-center rounded-md bg-green-50 px-2 py-1
             text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20">
  Badge
</span>

<!-- Avatar -->
<img class="inline-block h-10 w-10 rounded-full ring-2 ring-white"
     src="avatar.jpg" alt="Avatar">

<!-- Modal overlay -->
<div class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full">
  <div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white">
    Modal content
  </div>
</div>

State Variants

<!-- Hover -->
<button class="bg-blue-500 hover:bg-blue-700">Hover me</button>

<!-- Focus -->
<input class="focus:ring-2 focus:ring-blue-500 focus:outline-none">

<!-- Active -->
<button class="active:bg-blue-800">Click me</button>

<!-- Disabled -->
<button class="disabled:opacity-50 disabled:cursor-not-allowed" disabled>
  Disabled
</button>

<!-- Group hover -->
<div class="group">
  <p class="group-hover:text-blue-500">Hover parent to change</p>
</div>

<!-- Peer states -->
<input type="checkbox" class="peer" id="toggle">
<label class="peer-checked:text-blue-500">Checked state</label>

<!-- First/last child -->
<div class="first:pt-0 last:pb-0">List item</div>

<!-- Odd/even -->
<tr class="odd:bg-white even:bg-gray-50">Table row</tr>

Dark Mode

Configuration

// tailwind.config.js
module.exports = {
  darkMode: 'class', // or 'media' for system preference
  // ...
}

Usage

<!-- Dark mode with class strategy -->
<html class="dark">
  <body class="bg-white dark:bg-gray-900">
    <h1 class="text-gray-900 dark:text-white">
      Adapts to dark mode
    </h1>
    <p class="text-gray-600 dark:text-gray-300">
      Secondary text
    </p>
    <button class="bg-blue-500 dark:bg-blue-600
                   hover:bg-blue-600 dark:hover:bg-blue-700">
      Button
    </button>
  </body>
</html>

Toggle Implementation

// Dark mode toggle
function toggleDarkMode() {
  document.documentElement.classList.toggle('dark');
}

// Respect system preference
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
  document.documentElement.classList.add('dark');
}

// Persist preference
localStorage.setItem('theme', 'dark');

Dark Mode Patterns

<!-- Card with dark mode -->
<div class="bg-white dark:bg-gray-800 shadow-lg dark:shadow-gray-900/50
            rounded-lg p-6">
  <h2 class="text-gray-900 dark:text-white text-xl font-bold">
    Card Title
  </h2>
  <p class="text-gray-600 dark:text-gray-300 mt-2">
    Card content with proper contrast in both modes.
  </p>
  <button class="mt-4 bg-blue-500 dark:bg-blue-600 text-white
                 hover:bg-blue-600 dark:hover:bg-blue-500
                 px-4 py-2 rounded">
    Action
  </button>
</div>

<!-- Border colours in dark mode -->
<div class="border border-gray-200 dark:border-gray-700">
  Bordered content
</div>

<!-- Ring colours -->
<input class="ring-2 ring-blue-500 dark:ring-blue-400
              focus:ring-blue-600 dark:focus:ring-blue-300">

JIT Mode and Performance

Key Concepts

Just-In-Time (JIT) mode generates styles on-demand as you author your templates, resulting in lightning-fast build times and much smaller CSS files.

Benefits:

  • Instant build times during development
  • All variants enabled by default
  • Arbitrary value support
  • Better development experience

Configuration

// tailwind.config.js
module.exports = {
  // JIT is enabled by default in Tailwind CSS v3+
  content: [
    './src/**/*.{html,js,jsx,ts,tsx,vue}',
  ],
  // ...
}

Arbitrary Values

<!-- Arbitrary colours -->
<div class="bg-[#1da1f2] text-[rgb(255,255,255)]">
  Custom colour
</div>

<!-- Arbitrary spacing -->
<div class="p-[13px] m-[3.5rem] top-[117px]">
  Custom spacing
</div>

<!-- Arbitrary sizing -->
<div class="w-[calc(100%-2rem)] h-[500px] max-w-[1200px]">
  Custom sizing
</div>

<!-- Arbitrary font size -->
<p class="text-[22px] leading-[1.6]">
  Custom typography
</p>

<!-- Arbitrary grid -->
<div class="grid grid-cols-[1fr_500px_2fr]">
  Custom grid columns
</div>

<!-- Arbitrary animations -->
<div class="animate-[wiggle_1s_ease-in-out_infinite]">
  Custom animation
</div>

Performance Optimisation

// tailwind.config.js
module.exports = {
  // Ensure content paths are correct
  content: [
    './src/**/*.{js,jsx,ts,tsx}',
    './public/index.html',
    // Don't include node_modules!
  ],

  // Disable unused core plugins
  corePlugins: {
    float: false,
    objectFit: false,
    // Disable if not using
  },
}

Best Practices:

  1. Avoid dynamic class names:
<!-- Bad - classes won't be detected -->
<div class="text-{{ error ? 'red' : 'green' }}-500">

<!-- Good - use complete class names -->
<div class="{{ error ? 'text-red-500' : 'text-green-500' }}">
  1. Don't construct classes:
// Bad
const colour = 'blue';
const className = `bg-${colour}-500`;

// Good
const colourClasses = {
  blue: 'bg-blue-500',
  red: 'bg-red-500',
};
const className = colourClasses[colour];
  1. Use safelist for dynamic classes:
// tailwind.config.js
module.exports = {
  safelist: [
    'bg-red-500',
    'bg-green-500',
    'bg-blue-500',
    // Or use patterns
    {
      pattern: /bg-(red|green|blue)-(100|500|900)/,
    },
  ],
}

Common Layout Patterns

Centred Content

<!-- Horizontally and vertically centred -->
<div class="min-h-screen flex items-center justify-center">
  <div>Centred content</div>
</div>

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

<!-- Centred text content -->
<div class="max-w-prose mx-auto">
  <p>Long-form text content with optimal reading width</p>
</div>

Holy Grail Layout

<div class="min-h-screen flex flex-col">
  <!-- Header -->
  <header class="bg-gray-800 text-white p-4">
    Header
  </header>

  <!-- Main content area -->
  <div class="flex-1 flex flex-col md:flex-row">
    <!-- Sidebar -->
    <aside class="w-full md:w-64 bg-gray-100 p-4">
      Sidebar
    </aside>

    <!-- Main content -->
    <main class="flex-1 p-4">
      Main content
    </main>

    <!-- Optional right sidebar -->
    <aside class="w-full md:w-64 bg-gray-100 p-4">
      Right sidebar
    </aside>
  </div>

  <!-- Footer -->
  <footer class="bg-gray-800 text-white p-4">
    Footer
  </footer>
</div>

Sticky Footer

<div class="min-h-screen flex flex-col">
  <main class="flex-1">
    Main content
  </main>
  <footer class="bg-gray-800 text-white p-4">
    Footer stays at bottom
  </footer>
</div>

Responsive Grid Cards

<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6 p-6">
  <div class="bg-white rounded-lg shadow p-6">Card 1</div>
  <div class="bg-white rounded-lg shadow p-6">Card 2</div>
  <div class="bg-white rounded-lg shadow p-6">Card 3</div>
  <div class="bg-white rounded-lg shadow p-6">Card 4</div>
</div>

Sidebar Navigation

<div class="flex h-screen">
  <!-- Sidebar -->
  <div class="w-64 bg-gray-900 text-white flex flex-col">
    <div class="p-4 font-bold text-xl">Logo</div>
    <nav class="flex-1">
      <a href="#" class="block px-4 py-2 hover:bg-gray-800">Home</a>
      <a href="#" class="block px-4 py-2 hover:bg-gray-800">About</a>
      <a href="#" class="block px-4 py-2 hover:bg-gray-800">Contact</a>
    </nav>
  </div>

  <!-- Main content -->
  <div class="flex-1 overflow-y-auto p-6">
    Content
  </div>
</div>

Aspect Ratio Containers

<!-- 16:9 aspect ratio -->
<div class="aspect-video bg-gray-200">
  Video container
</div>

<!-- Square -->
<div class="aspect-square bg-gray-200">
  Square container
</div>

<!-- Custom aspect ratio -->
<div class="aspect-[4/3] bg-gray-200">
  4:3 container
</div>

Quick Reference

Category Classes Description
Display block, inline-block, flex, grid, hidden Element display type
Position static, relative, absolute, fixed, sticky Position scheme
Overflow overflow-auto, overflow-hidden, overflow-scroll Overflow behaviour
Z-Index z-0, z-10, z-20, z-50, z-auto Stack order
Opacity opacity-0, opacity-50, opacity-100 Element opacity
Cursor cursor-pointer, cursor-not-allowed, cursor-wait Cursor style
Pointer Events pointer-events-none, pointer-events-auto Pointer event behaviour
User Select select-none, select-text, select-all Text selection behaviour
Transition transition, duration-300, ease-in-out CSS transitions
Transform scale-110, rotate-45, translate-x-4 CSS transforms
Border border, border-2, rounded, rounded-lg Border styling
Shadow shadow, shadow-md, shadow-lg, shadow-xl Box shadows
Ring ring-2, ring-blue-500, ring-offset-2 Focus rings
Divide divide-y, divide-x, divide-gray-200 Borders between children

Commonly Used Combinations

<!-- Flex centre -->
flex items-center justify-center

<!-- Absolute centre -->
absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2

<!-- Truncate text -->
truncate overflow-hidden whitespace-nowrap

<!-- Focus ring -->
focus:outline-none focus:ring-2 focus:ring-blue-500

<!-- Smooth transition -->
transition-all duration-300 ease-in-out

<!-- Responsive hide/show -->
hidden md:block / md:hidden

<!-- Full-screen overlay -->
fixed inset-0 bg-black bg-opacity-50

<!-- Sticky header -->
sticky top-0 z-50 bg-white shadow

Common Issues and Solutions

Classes Not Applied

Problem: Tailwind classes aren't being applied to elements.

Solutions:

  1. Check that content paths in tailwind.config.js include your files
  2. Ensure the file extension is included in content paths
  3. Verify Tailwind CSS is properly imported in your CSS file
  4. Check for typos in class names
// tailwind.config.js
module.exports = {
  content: [
    './src/**/*.{js,jsx,ts,tsx}', // Include all relevant extensions
    './public/**/*.html',
  ],
}

Dynamic Classes Not Working

Problem: Dynamically constructed class names don't work.

Solution: Use complete class names or safelist patterns:

// Bad
`bg-${colour}-500`

// Good - complete class names
const colours = {
  red: 'bg-red-500',
  blue: 'bg-blue-500',
};

// Or safelist in config
module.exports = {
  safelist: ['bg-red-500', 'bg-blue-500'],
}

Large CSS Bundle Size

Problem: Production CSS is too large.

Solutions:

  1. Ensure content paths are specific (don't include node_modules)
  2. Remove unused utilities from safelist
  3. Verify you're running production build with minification
# Production build
NODE_ENV=production npx tailwindcss -i ./src/input.css -o ./dist/output.css --minify

Specificity Issues

Problem: Custom styles override Tailwind utilities.

Solution: Use @layer directive for custom styles:

@layer components {
  .btn {
    @apply px-4 py-2; /* Lower specificity, can be overridden */
  }
}

Dark Mode Not Working

Problem: Dark mode classes don't apply.

Solutions:

  1. Check darkMode setting in config ('class' or 'media')
  2. Ensure dark class is on html element (for class strategy)
  3. Verify dark variant classes are correct (dark:bg-gray-900)
// tailwind.config.js
module.exports = {
  darkMode: 'class', // Ensure this is set
}
<!-- Ensure dark class is on html -->
<html class="dark">

Responsive Classes Not Working

Problem: Breakpoint prefixes don't apply styles.

Solutions:

  1. Remember Tailwind is mobile-first (sm: and up, not sm: and down)
  2. Check screen size in browser matches breakpoint
  3. Ensure no conflicting media queries in custom CSS
<!-- Mobile first: base styles for mobile, then override for larger -->
<div class="p-4 md:p-8"> <!-- p-4 on mobile, p-8 on md and above -->

PurgeCSS Removing Needed Classes

Problem: Production build removes classes you need.

Solution: Safelist the classes or use complete class names:

// tailwind.config.js
module.exports = {
  safelist: [
    'bg-red-500',
    { pattern: /^bg-/ }, // Safelist all bg- classes
  ],
}

Conflicting with Other CSS

Problem: Tailwind conflicts with existing stylesheets.

Solution: Use prefix option in config:

// tailwind.config.js
module.exports = {
  prefix: 'tw-',
}
<!-- Usage -->
<div class="tw-bg-blue-500 tw-p-4">Prefixed classes</div>

Related Topics

To complement this Tailwind CSS cheatsheet, consider exploring these related topics:

  1. CSS Fundamentals - Deep understanding of CSS concepts (flexbox, grid, specificity) that Tailwind abstracts
  2. PostCSS - The tool that powers Tailwind's build process and enables custom plugins
  3. React/Vue/Svelte Components - Building component libraries with Tailwind in modern frameworks
  4. Design Systems - Creating consistent design tokens and component patterns with Tailwind
  5. Accessibility (a11y) - Ensuring Tailwind-built interfaces are accessible to all users
  6. CSS-in-JS Alternatives - Comparing Tailwind with styled-components, Emotion, and other approaches