| name | tailwind-css |
| description | Use when implementing or reviewing Tailwind CSS styling, responsive layouts, state variants, theme tokens, layers, grids, or build configuration. Use a design-system skill for visual direction and accessibility-wcag for formal accessibility review. |
| metadata | {"portable":true,"compatible_with":["Codex","codex"]} |
Tailwind CSS
Acknowledgement: Shared by Peter Bamuhigire, techguypeter.com, +256 784 464178.
Use When
- Tailwind CSS v3 utility-first styling — setup, responsive design, dark mode, event/state modifiers, tailwind.config.js customization (colors, spacing, screens, plugins), @apply and @layer directives, flexbox/grid classes, and best practices. Use...
Evidence Produced
| Category | Artifact | Format | Example |
|---|
| UX quality | Theme + responsive audit | Markdown doc reviewing tokens, breakpoint coverage, and dark-mode parity | docs/web/tailwind-theme-audit.md |
References
- Use the links and companion skills already referenced in this file when deeper context is needed.
Utility-first CSS framework. Style in HTML — no custom CSS required.
Setup
npx create-next-app@latest my-app --typescript --tailwind
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
tailwind.config.js (minimum):
module.exports = {
content: ['./src/**/*.{html,js,jsx,ts,tsx}'],
theme: { extend: {} },
plugins: [],
};
input.css:
@tailwind base;
@tailwind components;
@tailwind utilities;
CDN (prototyping only):
<script src="https://cdn.tailwindcss.com"></script>
Core Philosophy
Tailwind replaces custom CSS with composable utility classes directly on elements.
<div class="mainBlock">…</div>
<div class="bg-gray-500 p-2 w-72 rounded border border-gray-900 flex">…</div>
Utility classes vs inline styles:
- Utility classes are part of a design system — reusable, consistent
- Utility classes support responsive breakpoints and state variants
- Utility classes handle hover, focus, dark mode — inline styles cannot
Responsive Design
Mobile-first breakpoints. Apply a prefix to target that breakpoint and above.
| Prefix | Min-width | Equivalent CSS |
|---|
| (none) | 0px | Always applies |
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) |
<div class="bg-pink-500 sm:bg-red-500 md:bg-green-500 lg:bg-gray-500 xl:bg-blue-500">
Target a range (apply only between breakpoints):
<div class="sm:max-lg:bg-red-500">
<div class="sm:max-md:flex">
Event and State Modifiers
Format: {modifier}:{utility-class}
<button class="bg-green-300 hover:bg-blue-400 active:bg-red-500">Click</button>
<button class="hover:bg-green-500 hover:text-white">Hover me</button>
<input class="focus:outline-none focus:ring-2 focus:ring-blue-500" />
<input disabled class="disabled:bg-gray-200 disabled:cursor-not-allowed" />
<input required class="required:bg-red-50 invalid:border-red-500" />
<div class="first:font-bold last:italic">…</div>
<div class="odd:bg-green-100 even:bg-blue-100">…</div>
<div class="group">
<p class="text-gray-600 group-hover:text-black">Text changes on parent hover</p>
</div>
Dark Mode
System-controlled (default):
<div class="bg-white dark:bg-gray-900 text-black dark:text-white">
Manual toggle (class-based):
module.exports = { darkMode: 'class', ... }
<html id="root" class="dark">
<div class="bg-white dark:bg-gray-900">…</div>
</html>
document.getElementById('root').classList.toggle('dark');
Style Reuse — @apply and @layer
When repeating the same set of utility classes across many elements, extract to a component class.
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.btn-primary {
@apply px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition;
}
.card {
@apply bg-white rounded-xl shadow-md p-6;
}
}
@layer base {
h1 { @apply text-2xl font-bold; }
h2 { @apply text-xl font-semibold; }
a { @apply text-blue-600 underline; }
}
<button class="btn-primary">Save</button>
<div class="card">…</div>
Rule: Use @apply sparingly — prefer utility classes in JSX components.
Use it for global base styles (headings, links) and frequently repeated component patterns.
tailwind.config.js — Customisation
Custom Colors
module.exports = {
theme: {
extend: {
colors: {
'brand': '#1DA1F2',
'brand-dark': '#0c85d0',
'silver': '#C0C0C0',
},
},
},
};
Usage: bg-brand, text-silver
Color with shades:
colors: {
'primary': {
50: '#eff6ff',
100: '#dbeafe',
500: '#3b82f6',
900: '#1e3a5f',
},
}
Usage: bg-primary-500, text-primary-900
Arbitrary color (no config needed): bg-[#1DA1F2]
Custom Screens (Breakpoints)
theme: {
screens: {
'sm': '640px', 'md': '768px', 'lg': '1024px',
'xl': '1280px', '2xl': '1536px',
'3xl': '1800px',
'mobile': '480px',
},
},
Custom Spacing
theme: {
extend: {
spacing: {
'18': '4.5rem',
'72': '18rem',
'84': '21rem',
},
},
},
Disable Core Plugin
module.exports = { corePlugins: { container: false, preflight: false } }
Class Safelisting
Add classes that may not appear in scanned files (e.g., dynamically constructed):
module.exports = { safelist: ['bg-red-500', 'text-3xl', 'lg:text-4xl'] }
Plugins
npm install @tailwindcss/typography @tailwindcss/forms
plugins: [
require('@tailwindcss/typography'),
require('@tailwindcss/forms'),
],
Usage: <article class="prose lg:prose-xl">, <input class="form-input" />
Layout Quick Reference
<div class="container mx-auto px-4">
<div class="flex items-center justify-between gap-4">
<div class="flex flex-col gap-2">
<div class="flex flex-wrap">
<div class="grid grid-cols-3 gap-6">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="col-span-2">
<div class="grid grid-cols-[repeat(auto-fit,minmax(min(18rem,100%),1fr))] gap-[clamp(1rem,2vw,2rem)]">
<div class="relative">
<div class="absolute top-0 right-0">badge</div>
</div>
<div class="overflow-hidden">
<div class="overflow-x-auto">
Typography Quick Reference
<h1 class="text-4xl font-bold tracking-tight">
<p class="text-base text-gray-600 leading-relaxed">
<p class="text-gray-900 dark:text-gray-100">
<p class="text-center"> <p class="text-right">
<p class="truncate">
<p class="line-clamp-3">
<h1 class="text-[clamp(2.25rem,6vw,5rem)] leading-[1.05]">
Spacing, Sizing, Effects
<div class="p-4 mx-auto mt-8">
<div class="w-full max-w-2xl h-screen min-h-0">
<img class="w-16 h-16 object-cover rounded-full">
<div class="border border-gray-200 rounded-lg">
<div class="border-2 border-blue-500 rounded-xl ring-2 ring-blue-300">
<div class="shadow shadow-lg shadow-xl shadow-2xl">
<div class="opacity-50 hover:opacity-100 transition">
<button class="transition duration-200 ease-in-out hover:scale-105">
Common Component Patterns
<button class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700
active:bg-blue-800 transition disabled:opacity-50 disabled:cursor-not-allowed">
Primary
</button>
<div class="bg-white dark:bg-gray-800 rounded-2xl shadow-md p-6 hover:shadow-lg transition">
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs
font-medium bg-green-100 text-green-800">
Active
</span>
<input class="w-full px-3 py-2 border border-gray-300 rounded-lg
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent
dark:bg-gray-700 dark:border-gray-600 dark:text-white" />
<nav class="flex flex-col md:flex-row gap-2 md:gap-6">
Best Practices
| Rule | Reason |
|---|
Never include CSS files in content config | Causes false class detection |
Use complete class names (bg-red-500 not bg-${color}-500) | Dynamic strings aren't scanned |
Prefer @layer components over inline @apply in JSX | Keeps HTML clean for one-off reuse |
Use extend not override in theme | Preserve default utilities |
| Use framework components (React, Vue) instead of HTML loops | Class strings in components = clean repetition |
| Check Tailwind v3 docs for new classes | Classes added/renamed across versions |
| Use arbitrary values for mathematical relationships, not random decoration | clamp(), minmax(), calc(), aspect-ratio, and ch preserve proportion and responsiveness |
Source: Bhat — Ultimate Tailwind CSS Handbook (BPB, 2023)
Decision rules
| Condition | Choice | Failure avoided |
|---|
| Value is a reusable product token | Add a named theme token | Scattered arbitrary values |
| Value is a one-off mathematical constraint | Use an arbitrary value | Polluting the theme |
| Utility sequence repeats with stable semantics | Extract a component | Copy-paste drift |
Anti-Patterns
- Constructing dynamic fragments such as
bg-${color}-500. Fix: map to complete class strings.
- Replacing the default theme accidentally. Fix: extend it unless the design system owns every token.
- Using
@apply for every component. Fix: extract only stable repetition.
- Choosing arbitrary spacing without rationale. Fix: use tokens or a documented proportional constraint.
- Styling only the default state. Fix: cover focus, disabled, error, loading, empty, and dark states.
Capability contract
Read and search markup, configuration, and tokens first. Edit only when authorised; execute the existing build, lint, responsive checks, and accessibility checks when available.
Degraded mode
If the build or rendered interface is unavailable, provide exact changes and mark purge, contrast, responsive, and interaction-state checks as unverified.
Inputs
| Artefact | Required? | Purpose |
|---|
| Design tokens, responsive layouts, component states, and Tailwind version | yes | Map design to maintainable utilities |
Outputs
- Produce Tailwind implementation with responsive, state, accessibility, and consistency evidence.