Tech Guides
01

Quick Reference

The most-used Tailwind utilities at a glance. Every class maps directly to a CSS property-value pair.

Spacing

ClassCSSValue
p-4padding: 1rem16px
m-2margin: 0.5rem8px
px-6padding-left/right: 1.5rem24px
my-automargin-top/bottom: autoauto
space-x-4> * + * { margin-left: 1rem }16px gap
gap-3gap: 0.75rem12px

Layout

ClassCSS
flexdisplay: flex
griddisplay: grid
items-centeralign-items: center
justify-betweenjustify-content: space-between
grid-cols-3grid-template-columns: repeat(3, minmax(0, 1fr))
col-span-2grid-column: span 2 / span 2
hiddendisplay: none
blockdisplay: block

Typography

ClassCSS
text-lgfont-size: 1.125rem; line-height: 1.75rem
font-boldfont-weight: 700
text-centertext-align: center
leading-relaxedline-height: 1.625
tracking-wideletter-spacing: 0.025em
truncateoverflow: hidden; text-overflow: ellipsis; white-space: nowrap

Colors & Effects

ClassCSS
bg-blue-500background-color: #3b82f6
text-whitecolor: #fff
border-gray-200border-color: #e5e7eb
rounded-lgborder-radius: 0.5rem
shadow-mdbox-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1)...
opacity-50opacity: 0.5
ring-2box-shadow: 0 0 0 2px (ring-color)
02

Installation

Three official ways to add Tailwind to a project, depending on your build tool and framework.

Tailwind CLI Simplest

The standalone CLI requires no Node.js. Download the binary or use npx.

# Install via npm
npm install -D tailwindcss
npx tailwindcss init

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

# Or use the standalone CLI (no Node required)
curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64
chmod +x tailwindcss-linux-x64
./tailwindcss-linux-x64 -i input.css -o output.css

PostCSS Plugin Most Common

Integrates Tailwind into any PostCSS-based build pipeline.

# Install dependencies
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init
// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}

Vite Integration Modern

First-class support for Vite, Next.js, Nuxt, SvelteKit, and other modern frameworks.

# Vite + React example
npm create vite@latest my-app -- --template react
cd my-app
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p   # creates both config files
/* src/index.css — add the Tailwind directives */
@tailwind base;
@tailwind components;
@tailwind utilities;

Content Configuration

Tell Tailwind where your templates are so it can tree-shake unused classes.

// tailwind.config.js
module.exports = {
  content: [
    './index.html',
    './src/**/*.{js,ts,jsx,tsx,vue,svelte}',
    './components/**/*.html',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
Content Paths Are Critical
If a class isn't showing up in production, the most common cause is a missing content path. Tailwind scans these files for class names and only includes CSS for classes it finds.

CDN (Play / Prototyping) Dev Only

For quick experiments. Not recommended for production.

<script src="https://cdn.tailwindcss.com"></script>

<!-- Customize the config inline -->
<script>
  tailwind.config = {
    theme: {
      extend: {
        colors: { brand: '#0ea5e9' }
      }
    }
  }
</script>
03

Utility-First Philosophy

Instead of writing custom CSS for every component, compose designs directly in markup using small, single-purpose utility classes.

Traditional CSS vs. Utility-First

Traditional CSS
/* styles.css */
.card {
  background: white;
  border-radius: 0.5rem;
  padding: 1.5rem;
  box-shadow: 0 1px 3px
    rgba(0,0,0,0.1);
}
.card-title {
  font-size: 1.25rem;
  font-weight: 600;
  color: #1f2937;
}
Utility-First
<div class="
  bg-white
  rounded-lg
  p-6
  shadow
">
  <h2 class="
    text-xl
    font-semibold
    text-gray-800
  ">
    Title
  </h2>
</div>

Why Utility-First?

  • No naming overhead — Stop inventing class names like .card-wrapper-inner. The utility describes exactly what it does.
  • CSS stops growing — With traditional CSS, your stylesheet grows with every feature. With utilities, the same classes are reused across the entire project.
  • Safe to change — Changing a utility class in HTML is local. You never worry about breaking something else by editing shared CSS.
  • Consistent design — Utilities are constrained to your design system's scale. p-4 is always 1rem, not "whatever padding this component needs".
  • Responsive & state variants — Apply styles conditionally with prefixes: md:flex, hover:bg-blue-600, dark:text-white.

The "Ugly HTML" Objection

A common criticism is that utility classes make HTML verbose. In practice:

  • Components solve it — In React/Vue/Svelte, you write the utility classes once in a component and reuse the component.
  • @apply for extraction — Pull repeated utility patterns into custom classes when needed.
  • Multi-cursor editing — Modern editors make it easy to change classes across multiple instances.
  • CSS purging keeps output tiny — Tailwind's production CSS is typically 5-10 KB gzipped, regardless of how many utilities exist.
04

Spacing & Sizing Scale

Tailwind's spacing scale is shared across padding, margin, width, height, gap, and more. One scale, consistent everywhere.

The Default Spacing Scale

00px
px1px
0.50.125rem
10.25rem
20.5rem
30.75rem
41rem
61.5rem
82rem
123rem
164rem
246rem
328rem
4812rem
6416rem
9624rem

Spacing Prefixes

PrefixPropertyExample
p-padding (all sides)p-4 → padding: 1rem
px- / py-padding horizontal / verticalpx-6 → padding-left/right: 1.5rem
pt- pb- pl- pr-padding individual sidespt-2 → padding-top: 0.5rem
m-margin (all sides)m-4 → margin: 1rem
mx- / my-margin horizontal / verticalmx-auto → margin-left/right: auto
-m-negative margin-mt-4 → margin-top: -1rem
space-x- / space-y-child gap (lobotomized owl)space-y-4 → > * + * margin-top: 1rem
gap-flex/grid gapgap-4 → gap: 1rem

Width & Height

ClassCSS
w-fullwidth: 100%
w-screenwidth: 100vw
w-autowidth: auto
w-1/2width: 50%
w-64width: 16rem (256px)
max-w-mdmax-width: 28rem (448px)
max-w-screen-xlmax-width: 1280px
min-h-screenmin-height: 100vh
h-fitheight: fit-content
size-10width: 2.5rem; height: 2.5rem
05

Colors & Customization

Tailwind ships with a curated palette of 22 color families, each with 11 shades (50-950). Every color is designed to be accessible and harmonious.

Color Palette (Selection)

slate-50
slate-500
slate-900
red-500
orange-500
yellow-500
green-500
sky-500
blue-500
indigo-500
purple-500
pink-500

Color Usage Patterns

UtilityPurposeExample
bg-{color}-{shade}Backgroundbg-blue-500
text-{color}-{shade}Text colortext-gray-700
border-{color}-{shade}Border colorborder-red-300
ring-{color}-{shade}Focus ringring-blue-500
divide-{color}-{shade}Divider between childrendivide-gray-200
placeholder-{color}Input placeholderplaceholder-gray-400
from- via- to-Gradient stopsfrom-sky-400 to-indigo-500

Opacity Modifier

Append a slash and opacity value to any color utility.

<!-- Background with 50% opacity -->
<div class="bg-black/50">Semi-transparent overlay</div>

<!-- Text with 75% opacity -->
<p class="text-white/75">Slightly faded text</p>

<!-- Border with 20% opacity -->
<div class="border border-white/20"></div>

Custom Colors in Config

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        // Simple single color
        brand: '#0ea5e9',

        // Full shade scale
        brand: {
          50:  '#f0f9ff',
          100: '#e0f2fe',
          500: '#0ea5e9',
          900: '#0c4a6e',
        },

        // Using CSS variables (v3.1+)
        primary: 'rgb(var(--color-primary) / <alpha-value>)',
      },
    },
  },
}
06

Typography

Font size, weight, family, line height, letter spacing, text decoration, and text transform utilities.

Font Size Scale

ClassSizeLine Height
text-xs0.75rem (12px)1rem
text-sm0.875rem (14px)1.25rem
text-base1rem (16px)1.5rem
text-lg1.125rem (18px)1.75rem
text-xl1.25rem (20px)1.75rem
text-2xl1.5rem (24px)2rem
text-4xl2.25rem (36px)2.5rem
text-6xl3.75rem (60px)1
text-9xl8rem (128px)1

Font Weight & Family

ClassCSS
font-thinfont-weight: 100
font-lightfont-weight: 300
font-normalfont-weight: 400
font-mediumfont-weight: 500
font-semiboldfont-weight: 600
font-boldfont-weight: 700
font-blackfont-weight: 900
font-sansfont-family: ui-sans-serif, system-ui, ...
font-seriffont-family: ui-serif, Georgia, ...
font-monofont-family: ui-monospace, SFMono-Regular, ...

Text Utilities

ClassPurpose
leading-tightline-height: 1.25
leading-relaxedline-height: 1.625
tracking-tightletter-spacing: -0.025em
tracking-wideletter-spacing: 0.025em
uppercasetext-transform: uppercase
capitalizetext-transform: capitalize
underlinetext-decoration-line: underline
line-throughtext-decoration-line: line-through
no-underlinetext-decoration-line: none
truncateoverflow: hidden + ellipsis + nowrap
line-clamp-3Truncate to 3 lines with ellipsis
text-balancetext-wrap: balance (v3.4+)

Custom Fonts

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      fontFamily: {
        sans: ['Inter', 'system-ui', 'sans-serif'],
        display: ['Lexend', 'sans-serif'],
        mono: ['JetBrains Mono', 'monospace'],
      },
    },
  },
}

<!-- Usage: -->
<h1 class="font-display text-4xl">Custom Heading</h1>
07

Flexbox & Grid

Layout utilities for building any arrangement from simple rows to complex responsive grids.

Flexbox

ClassCSS
flexdisplay: flex
inline-flexdisplay: inline-flex
flex-rowflex-direction: row
flex-colflex-direction: column
flex-wrapflex-wrap: wrap
flex-1flex: 1 1 0%
flex-noneflex: none
growflex-grow: 1
shrink-0flex-shrink: 0
items-centeralign-items: center
items-startalign-items: flex-start
justify-betweenjustify-content: space-between
justify-centerjustify-content: center
<!-- Centered row with space between -->
<nav class="flex items-center justify-between px-6 py-4">
  <div class="font-bold text-xl">Logo</div>
  <div class="flex gap-4">
    <a href="#">Home</a>
    <a href="#">About</a>
  </div>
</nav>

CSS Grid

ClassCSS
griddisplay: grid
grid-cols-1grid-template-columns: repeat(1, minmax(0, 1fr))
grid-cols-3grid-template-columns: repeat(3, minmax(0, 1fr))
grid-cols-12grid-template-columns: repeat(12, minmax(0, 1fr))
grid-rows-2grid-template-rows: repeat(2, minmax(0, 1fr))
col-span-2grid-column: span 2 / span 2
col-start-1grid-column-start: 1
row-span-3grid-row: span 3 / span 3
auto-cols-frgrid-auto-columns: minmax(0, 1fr)
<!-- Responsive card grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
  <div class="bg-white rounded-xl p-6 shadow-sm">Card 1</div>
  <div class="bg-white rounded-xl p-6 shadow-sm">Card 2</div>
  <div class="bg-white rounded-xl p-6 shadow-sm">Card 3</div>
</div>

<!-- 12-column layout -->
<div class="grid grid-cols-12 gap-4">
  <aside class="col-span-3">Sidebar</aside>
  <main class="col-span-9">Content</main>
</div>

Positioning

ClassCSS
relativeposition: relative
absoluteposition: absolute
fixedposition: fixed
stickyposition: sticky
inset-0top/right/bottom/left: 0
top-4top: 1rem
z-10z-index: 10
z-50z-index: 50
08

Responsive Breakpoints

Tailwind uses a mobile-first breakpoint system. Unprefix utilities target all screens; breakpoint prefixes apply at that width and up.

Default Breakpoints

PrefixMin WidthCSS
(none)0pxAll screens (mobile first)
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 in Practice

<!-- Stacked on mobile, side-by-side on md+, 3 columns on lg+ -->
<div class="
  flex flex-col          <!-- mobile: column -->
  md:flex-row            <!-- md+: row -->
  gap-4
">
  ...
</div>

<!-- Responsive text size -->
<h1 class="text-2xl md:text-4xl lg:text-6xl font-bold">
  Responsive Heading
</h1>

<!-- Show/hide based on screen size -->
<nav class="hidden md:flex gap-4">Desktop nav</nav>
<button class="md:hidden">Menu</button>
Mobile First Means Minimum Width
md:flex means "display: flex at 768px and above," not "only at 768px." Design for mobile first, then layer on larger screen styles.

Custom Breakpoints

// tailwind.config.js
module.exports = {
  theme: {
    screens: {
      sm: '480px',    // override default
      md: '768px',
      lg: '1024px',
      xl: '1280px',
      '2xl': '1536px',
      '3xl': '1920px',  // custom addition
    },
  },
}

// Max-width breakpoints (v3.2+)
module.exports = {
  theme: {
    screens: {
      'max-md': { max: '767px' },
      'tablet': { min: '768px', max: '1023px' },
    },
  },
}

Container

<!-- Centered, responsive max-width container -->
<div class="container mx-auto px-4">
  <!-- sm: max-width 640px, md: 768px, lg: 1024px, etc. -->
</div>

// Customize container behavior
module.exports = {
  theme: {
    container: {
      center: true,
      padding: '2rem',
      screens: {
        '2xl': '1400px',  // cap at 1400px on large screens
      },
    },
  },
}
09

States & Variants

Apply styles conditionally using state prefixes. Hover, focus, active, disabled, group, peer, and more.

Pseudo-Class Variants

PrefixSelectorExample
hover::hoverhover:bg-blue-700
focus::focusfocus:ring-2
focus-visible::focus-visiblefocus-visible:outline-2
focus-within::focus-withinfocus-within:border-blue-500
active::activeactive:bg-blue-800
disabled::disableddisabled:opacity-50
first::first-childfirst:rounded-t-lg
last::last-childlast:border-b-0
odd::nth-child(odd)odd:bg-gray-50
placeholder:::placeholderplaceholder:text-gray-400

Interactive Button Example

<button class="
  bg-sky-500
  hover:bg-sky-600
  active:bg-sky-700
  focus-visible:ring-2 focus-visible:ring-sky-300 focus-visible:outline-none
  disabled:opacity-50 disabled:cursor-not-allowed
  text-white font-semibold
  px-6 py-2.5 rounded-lg
  transition-colors duration-150
">
  Click me
</button>

Group & Peer Variants

Style elements based on the state of a parent (group) or sibling (peer).

<!-- Group: style children when parent is hovered -->
<a href="#" class="group block p-4 rounded-lg hover:bg-sky-50">
  <h3 class="font-semibold group-hover:text-sky-600">Title</h3>
  <p class="text-gray-500 group-hover:text-gray-700">Description</p>
  <span class="text-sky-500 opacity-0 group-hover:opacity-100 transition">&rarr;</span>
</a>

<!-- Peer: style based on sibling state -->
<input type="email" class="peer ..." placeholder="Email" />
<p class="hidden peer-invalid:block text-red-500 text-sm">
  Please enter a valid email
</p>

Other Useful Variants

PrefixPurpose
before: / after:Style ::before / ::after pseudo-elements
file:Style file input buttons
marker:Style list markers
selection:Style text selection
open:Style open <details> / <dialog>
has-[...]:Style parent based on child match (v3.4+)
10

Dark Mode

First-class dark mode support using the dark: prefix. Works with OS preference or manual class toggling.

Two Strategies

Media Strategy (Default)

Uses prefers-color-scheme media query. Automatic, no JS needed.

// tailwind.config.js
module.exports = {
  darkMode: 'media',
}
Class Strategy

Toggle via a .dark class on <html>. Gives user control.

// tailwind.config.js
module.exports = {
  darkMode: 'class',
}

// Or 'selector' in v3.4+
darkMode: 'selector',

Dark Mode in Practice

<div class="
  bg-white         dark:bg-slate-900
  text-gray-900    dark:text-white
  border-gray-200  dark:border-slate-700
  rounded-xl p-6 border
">
  <h2 class="text-xl font-bold">Card Title</h2>
  <p class="text-gray-600 dark:text-gray-400">
    This card adapts to dark mode automatically.
  </p>
</div>

Dark Mode Toggle (JS)

// Toggle dark mode with class strategy
const toggle = () => {
  const html = document.documentElement;
  html.classList.toggle('dark');
  localStorage.setItem('theme',
    html.classList.contains('dark') ? 'dark' : 'light'
  );
};

// Restore on page load (put in <head> to prevent flash)
if (localStorage.theme === 'dark' ||
    (!('theme' in localStorage) &&
     window.matchMedia('(prefers-color-scheme: dark)').matches)) {
  document.documentElement.classList.add('dark');
}
11

Configuration

The tailwind.config.js file is the single source of truth for your design system. Extend defaults, add custom values, or replace them entirely.

Config Structure

// tailwind.config.js (v3)
const defaultTheme = require('tailwindcss/defaultTheme');

module.exports = {
  content: ['./src/**/*.{html,js,jsx,tsx}'],
  darkMode: 'class',
  theme: {
    // Override defaults entirely
    screens: {
      sm: '480px',
      md: '768px',
      lg: '1024px',
      xl: '1280px',
    },
    extend: {
      // Add to defaults (don't replace)
      colors: {
        brand: {
          50:  '#f0f9ff',
          500: '#0ea5e9',
          900: '#0c4a6e',
        },
      },
      fontFamily: {
        sans: ['Inter', ...defaultTheme.fontFamily.sans],
      },
      spacing: {
        '18': '4.5rem',
        '128': '32rem',
      },
      borderRadius: {
        '4xl': '2rem',
      },
      animation: {
        'fade-in': 'fadeIn 0.5s ease-out',
      },
      keyframes: {
        fadeIn: {
          '0%': { opacity: '0' },
          '100%': { opacity: '1' },
        },
      },
    },
  },
  plugins: [
    require('@tailwindcss/typography'),
    require('@tailwindcss/forms'),
    require('@tailwindcss/container-queries'),
  ],
}

Extend vs. Override

Important Distinction
Keys inside theme.extend are added to the defaults. Keys directly in theme replace the defaults entirely. If you put colors directly in theme (not extend), you lose all of Tailwind's default colors.

JIT Mode (Just-In-Time)

Since Tailwind v3, JIT is the default engine. It generates styles on-demand as you author classes, enabling:

  • Instant build times — Only generates CSS for classes you actually use
  • Arbitrary valuesw-[137px], bg-[#1a1a2e], grid-cols-[200px_1fr]
  • All variants enabled — No need to configure which variants are active
  • Development and production parity — Same CSS in both environments

Presets

Share configuration across projects using presets.

// company-preset.js
module.exports = {
  theme: {
    extend: {
      colors: { brand: '#0ea5e9' },
      fontFamily: { sans: ['Inter'] },
    },
  },
}

// tailwind.config.js
module.exports = {
  presets: [require('./company-preset')],
  // project-specific overrides on top
}
12

@apply & Extraction

When you find yourself repeating the same utility combinations, extract them into custom classes or components.

@apply Directive

Pull utility classes into custom CSS.

/* In your CSS file */
@layer components {
  .btn {
    @apply px-4 py-2 font-semibold rounded-lg
           transition-colors duration-150;
  }

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

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

  .card {
    @apply bg-white dark:bg-slate-800
           rounded-xl shadow-md p-6
           border border-gray-200 dark:border-slate-700;
  }

  .input {
    @apply w-full rounded-lg border border-gray-300
           px-3 py-2 text-sm
           focus:ring-2 focus:ring-sky-500 focus:border-sky-500
           dark:bg-slate-900 dark:border-slate-600;
  }
}

CSS Layers

Tailwind has three layers that control specificity and ordering.

LayerPurposePriority
@layer baseResets, global defaults, element stylesLowest
@layer componentsReusable component classes (.btn, .card)Middle
@layer utilitiesSingle-purpose utility classesHighest
@layer base {
  h1 { @apply text-3xl font-bold; }
  h2 { @apply text-2xl font-semibold; }
  a  { @apply text-sky-500 hover:text-sky-600; }
}

@layer utilities {
  .text-shadow {
    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
  }
}

When to Use @apply

Best Practice
Prefer components over @apply. In React/Vue/Svelte, create a <Button> component with utility classes inline. Use @apply mainly for: (1) third-party content you can't control, (2) very long class strings in non-component templates, (3) base element styles.
13

Arbitrary Values & Properties

When Tailwind's design tokens don't cover your exact need, use bracket notation to specify any CSS value inline.

Arbitrary Values

Use square brackets to set any value for existing utility types.

<!-- Exact widths and heights -->
<div class="w-[137px] h-[calc(100vh-80px)]"></div>

<!-- Custom colors -->
<div class="bg-[#1a1a2e] text-[rgb(255,200,0)]"></div>

<!-- Grid template columns -->
<div class="grid grid-cols-[200px_1fr_200px]"></div>

<!-- Font sizes -->
<h1 class="text-[clamp(1.5rem,4vw,3rem)]">Fluid text</h1>

<!-- Margin with CSS variables -->
<div class="mt-[var(--header-height)]"></div>

<!-- Responsive arbitrary values -->
<div class="w-full md:w-[720px] lg:w-[960px]"></div>

Arbitrary Properties

Use any CSS property, even ones Tailwind doesn't have a built-in utility for.

<!-- Any CSS property -->
<div class="[mask-type:alpha]"></div>

<!-- Complex backdrop filter -->
<div class="[backdrop-filter:blur(12px)_saturate(180%)]"></div>

<!-- Scroll behavior -->
<div class="[scroll-snap-type:x_mandatory]"></div>

<!-- With variants -->
<div class="hover:[transform:rotateY(180deg)]"></div>

Arbitrary Variants

Target any CSS selector using bracket syntax.

<!-- Style a child element -->
<div class="[&_p]:text-gray-600">
  <p>This paragraph is gray</p>
</div>

<!-- nth-child -->
<ul class="[&>:nth-child(3)]:underline">...</ul>

<!-- Data attributes -->
<div class="[&[data-active]]:bg-sky-100"></div>

<!-- @supports query -->
<div class="[@supports(display:grid)]:grid"></div>
14

Plugins

Extend Tailwind with official and community plugins, or write your own to add custom utilities, components, and variants.

Official Plugins

@tailwindcss/typography

Beautiful typographic defaults for rendered HTML content (Markdown, CMS). Uses the prose class.

<article class="prose lg:prose-xl">
  {{ markdown_content }}
</article>
@tailwindcss/forms

Resets form elements to be easy to style with utilities. Normalizes inputs, selects, textareas, checkboxes.

<input type="text"
  class="rounded-md border-gray-300
  focus:ring-sky-500">
@tailwindcss/container-queries

Container query utilities: @container and @sm:, @md:, etc.

<div class="@container">
  <div class="@md:flex
    @lg:grid-cols-2">
  </div>
</div>
@tailwindcss/aspect-ratio

Aspect ratio utilities for older browsers. Modern browsers can use the built-in aspect-video / aspect-square.

<div class="aspect-w-16
  aspect-h-9">
  <iframe ...></iframe>
</div>

Writing a Plugin

const plugin = require('tailwindcss/plugin');

module.exports = {
  plugins: [
    plugin(function({ addUtilities, addComponents, matchUtilities, theme }) {
      // Add static utilities
      addUtilities({
        '.text-shadow-sm': {
          textShadow: '0 1px 2px rgba(0,0,0,0.1)',
        },
        '.text-shadow-lg': {
          textShadow: '0 4px 8px rgba(0,0,0,0.2)',
        },
      });

      // Add dynamic utilities (generates from theme values)
      matchUtilities(
        {
          'text-shadow': (value) => ({
            textShadow: value,
          }),
        },
        { values: theme('textShadow') }
      );

      // Add component classes
      addComponents({
        '.btn': {
          padding: '.5rem 1rem',
          borderRadius: '.25rem',
          fontWeight: '600',
        },
      });
    }),
  ],
}

Popular Community Plugins

PluginDescription
tailwindcss-animateAnimation utilities (used by shadcn/ui)
tailwind-mergeMerge conflicting classes intelligently in JS
daisyUIComponent library built on Tailwind utilities
tailwind-variantsFirst-class variant API (like CVA but Tailwind-native)
clsx / cvaConditional class composition and variant management
15

Component Patterns

Common UI patterns built entirely with Tailwind utilities. Copy-paste these as starting points.

Navbar

<nav class="flex items-center justify-between px-6 py-4
     bg-white/80 backdrop-blur-md border-b border-gray-200
     sticky top-0 z-50">
  <a class="text-xl font-bold text-gray-900">Logo</a>
  <div class="hidden md:flex items-center gap-6">
    <a class="text-gray-600 hover:text-gray-900 transition">Features</a>
    <a class="text-gray-600 hover:text-gray-900 transition">Pricing</a>
    <a class="bg-sky-500 text-white px-4 py-2 rounded-lg
       hover:bg-sky-600 transition">Get Started</a>
  </div>
</nav>

Card with Image

<div class="group overflow-hidden rounded-2xl bg-white shadow-md
     hover:shadow-xl transition-shadow duration-300">
  <img class="w-full h-48 object-cover
       group-hover:scale-105 transition-transform duration-300"
       src="..." alt="..." />
  <div class="p-6">
    <span class="text-xs font-medium uppercase tracking-wide
           text-sky-600">Category</span>
    <h3 class="text-lg font-semibold text-gray-900 mt-2">Title</h3>
    <p class="text-gray-600 mt-2 line-clamp-2">Description...</p>
  </div>
</div>

Form with Validation States

<form class="space-y-6 max-w-md mx-auto">
  <div>
    <label class="block text-sm font-medium text-gray-700 mb-1">
      Email
    </label>
    <input type="email" class="
      w-full rounded-lg border border-gray-300
      px-3 py-2 text-sm shadow-sm
      placeholder:text-gray-400
      focus:outline-none focus:ring-2 focus:ring-sky-500 focus:border-sky-500
      invalid:border-red-500 invalid:ring-red-500
    " />
  </div>
  <button class="
    w-full bg-sky-500 text-white font-semibold
    py-2.5 px-4 rounded-lg shadow-sm
    hover:bg-sky-600 focus-visible:outline focus-visible:outline-2
    focus-visible:outline-offset-2 focus-visible:outline-sky-500
    disabled:opacity-50 disabled:cursor-not-allowed
  ">Submit</button>
</form>

Centered Hero Section

<section class="relative isolate overflow-hidden
         bg-gradient-to-b from-sky-50 to-white
         px-6 py-24 sm:py-32 lg:px-8">
  <div class="mx-auto max-w-2xl text-center">
    <p class="text-sm font-semibold text-sky-600 uppercase
       tracking-wide">Introducing v4</p>
    <h1 class="mt-2 text-4xl font-bold tracking-tight
       text-gray-900 sm:text-6xl text-balance">
      Build faster, ship sooner
    </h1>
    <p class="mt-6 text-lg leading-8 text-gray-600">
      A utility-first CSS framework packed with classes
      that can be composed to build any design.
    </p>
    <div class="mt-10 flex items-center justify-center gap-4">
      <a class="bg-sky-500 text-white px-6 py-3 rounded-xl
         font-semibold shadow-lg hover:bg-sky-600">Get Started</a>
      <a class="text-gray-700 font-semibold">Docs &rarr;</a>
    </div>
  </div>
</section>
16

Tailwind v4 Changes

Tailwind CSS v4 is a ground-up rewrite. CSS-first configuration, new engine, and breaking changes from v3.

What Changed v4

  • CSS-first configuration — No more tailwind.config.js. Configure everything in CSS with @theme.
  • Zero-config content detection — Automatic source detection, no content array needed.
  • New high-performance engine — Full builds up to 10x faster, incremental builds 100x+ faster.
  • CSS import via @import "tailwindcss" — Replaces the three @tailwind directives.
  • Native CSS cascade layers — Uses @layer from the CSS spec, not Tailwind's custom @layer.
  • Built-in @starting-style — Entry animations without JS.
  • Container queries built in — No plugin needed. Use @sm:, @md:, etc.
  • New 3D transform utilitiesrotate-x-*, rotate-y-*, perspective-*.
  • Modernized P3 color palette — Colors use oklch for wider gamut displays.

@theme Directive (CSS-First Config)

/* v4: Configure your design system in CSS */
@import "tailwindcss";

@theme {
  /* Colors */
  --color-brand-50: #f0f9ff;
  --color-brand-500: #0ea5e9;
  --color-brand-900: #0c4a6e;

  /* Fonts */
  --font-sans: "Inter", sans-serif;
  --font-display: "Lexend", sans-serif;

  /* Breakpoints */
  --breakpoint-sm: 480px;
  --breakpoint-3xl: 1920px;

  /* Custom spacing */
  --spacing-18: 4.5rem;

  /* Animations */
  --animate-fade-in: fadeIn 0.5s ease-out;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

v3 to v4 Migration

v3 (tailwind.config.js)
module.exports = {
  content: ['./src/**/*.tsx'],
  theme: {
    extend: {
      colors: {
        brand: '#0ea5e9',
      },
    },
  },
}
v4 (CSS)
@import "tailwindcss";

@theme {
  --color-brand: #0ea5e9;
}

/* Content detection
   is automatic! */

Renamed & Removed Utilities

v3v4Note
bg-opacity-50bg-black/50Opacity modifier syntax
text-opacity-75text-white/75Opacity modifier syntax
decoration-clonebox-decoration-cloneRenamed
flex-grow / flex-shrinkgrow / shrinkShortened (already in v3)
overflow-ellipsistext-ellipsisRenamed

Installation (v4)

# Install Tailwind CSS v4
npm install tailwindcss@next @tailwindcss/vite

// vite.config.ts
import tailwindcss from '@tailwindcss/vite';

export default {
  plugins: [tailwindcss()],
}

/* src/app.css — one line replaces the three @tailwind directives */
@import "tailwindcss";

Upgrade Tool

# Automated codemod for migrating from v3 to v4
npx @tailwindcss/upgrade@next

# What it does:
# - Converts tailwind.config.js to @theme in CSS
# - Updates deprecated class names
# - Replaces @tailwind directives with @import
# - Updates PostCSS config
v4 is a Major Release
Tailwind v4 is not a drop-in replacement. Review the upgrade guide carefully. The automated tool handles most changes, but custom plugins and complex configurations may need manual updates.

Typography Plugin (v4)

In v4, the typography plugin is built into Tailwind. The prose class works without installing any plugin.

/* v4: just import Tailwind, prose is built in */
@import "tailwindcss";

<!-- Usage is the same -->
<article class="prose lg:prose-xl dark:prose-invert">
  <h1>My Blog Post</h1>
  <p>Beautiful default typography...</p>
</article>

<!-- Customize prose colors via @theme -->
@theme {
  --color-prose-body: var(--color-gray-700);
  --color-prose-headings: var(--color-gray-900);
  --color-prose-links: var(--color-sky-600);
}