tailwind-css/SKILL.md
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...
npx skillsauth add peterbamuhigire/skills-web-dev tailwind-cssInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
tailwind-css or would be better handled by a more specific companion skill.SKILL.md first, then load only the referenced deep-dive files that are necessary for the task.Utility-first CSS framework. Style in HTML — no custom CSS required.
# Next.js (includes Tailwind automatically)
npx create-next-app@latest my-app --typescript --tailwind
# Standalone (any project)
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
tailwind.config.js (minimum):
/** @type {import('tailwindcss').Config} */
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>
Tailwind replaces custom CSS with composable utility classes directly on elements.
<!-- Traditional CSS approach -->
<div class="mainBlock">…</div>
<!-- Tailwind utility-first approach -->
<div class="bg-gray-500 p-2 w-72 rounded border border-gray-900 flex">…</div>
Utility classes vs inline styles:
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) |
<!-- Pink on mobile, red sm+, green md+, gray lg+, blue xl+ -->
<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"> <!-- only sm to lg -->
<div class="sm:max-md:flex"> <!-- flex only at sm width -->
Format: {modifier}:{utility-class}
<!-- hover, active, focus -->
<button class="bg-green-300 hover:bg-blue-400 active:bg-red-500">Click</button>
<!-- Multiple on same event -->
<button class="hover:bg-green-500 hover:text-white">Hover me</button>
<!-- focus -->
<input class="focus:outline-none focus:ring-2 focus:ring-blue-500" />
<!-- disabled -->
<input disabled class="disabled:bg-gray-200 disabled:cursor-not-allowed" />
<!-- required / invalid -->
<input required class="required:bg-red-50 invalid:border-red-500" />
<!-- first-child / last-child -->
<div class="first:font-bold last:italic">…</div>
<!-- odd / even children -->
<div class="odd:bg-green-100 even:bg-blue-100">…</div>
<!-- group — parent hover affects children -->
<div class="group">
<p class="text-gray-600 group-hover:text-black">Text changes on parent hover</p>
</div>
System-controlled (default):
<div class="bg-white dark:bg-gray-900 text-black dark:text-white">
Manual toggle (class-based):
// tailwind.config.js
module.exports = { darkMode: 'class', ... }
<!-- Add/remove 'dark' class on root element via JS -->
<html id="root" class="dark">
<div class="bg-white dark:bg-gray-900">…</div>
</html>
// Toggle dark mode
document.getElementById('root').classList.toggle('dark');
When repeating the same set of utility classes across many elements, extract to a component class.
/* input.css */
@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.
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]
theme: {
screens: {
'sm': '640px', 'md': '768px', 'lg': '1024px',
'xl': '1280px', '2xl': '1536px',
'3xl': '1800px', // custom extra-large
'mobile': '480px', // custom named breakpoint
},
},
theme: {
extend: {
spacing: {
'18': '4.5rem',
'72': '18rem',
'84': '21rem',
},
},
},
module.exports = { corePlugins: { container: false, preflight: false } }
Add classes that may not appear in scanned files (e.g., dynamically constructed):
module.exports = { safelist: ['bg-red-500', 'text-3xl', 'lg:text-4xl'] }
npm install @tailwindcss/typography @tailwindcss/forms
plugins: [
require('@tailwindcss/typography'), // .prose classes for rich text
require('@tailwindcss/forms'), // styled form controls
],
Usage: <article class="prose lg:prose-xl">, <input class="form-input" />
<!-- Container (centers content at breakpoint) -->
<div class="container mx-auto px-4">
<!-- Flexbox -->
<div class="flex items-center justify-between gap-4">
<div class="flex flex-col gap-2">
<div class="flex flex-wrap">
<!-- Grid -->
<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"> <!-- span 2 columns -->
<!-- Position -->
<div class="relative">
<div class="absolute top-0 right-0">badge</div>
</div>
<!-- Overflow -->
<div class="overflow-hidden">
<div class="overflow-x-auto">
<!-- Font size: text-xs text-sm text-base text-lg text-xl text-2xl … text-9xl -->
<h1 class="text-4xl font-bold tracking-tight">
<p class="text-base text-gray-600 leading-relaxed">
<!-- Font weight -->
<!-- font-thin font-light font-normal font-medium font-semibold font-bold font-extrabold -->
<!-- Text color: text-{color}-{shade} -->
<p class="text-gray-900 dark:text-gray-100">
<!-- Text align -->
<p class="text-center"> <p class="text-right">
<!-- Truncate long text -->
<p class="truncate"> <!-- single line -->
<p class="line-clamp-3"> <!-- 3 lines then … -->
<!-- Padding/Margin: p-{n} px-{n} py-{n} pt/pr/pb/pl-{n} -->
<!-- n = 0,1,2,3,4,5,6,8,10,12,16,20,24,32,40,48,64 (0.25rem each) -->
<div class="p-4 mx-auto mt-8">
<!-- Width/Height -->
<div class="w-full max-w-2xl h-screen min-h-0">
<img class="w-16 h-16 object-cover rounded-full">
<!-- Borders -->
<div class="border border-gray-200 rounded-lg">
<div class="border-2 border-blue-500 rounded-xl ring-2 ring-blue-300">
<!-- Shadow -->
<div class="shadow shadow-lg shadow-xl shadow-2xl">
<!-- Opacity -->
<div class="opacity-50 hover:opacity-100 transition">
<!-- Transitions -->
<button class="transition duration-200 ease-in-out hover:scale-105">
<!-- Button variants -->
<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>
<!-- Card -->
<div class="bg-white dark:bg-gray-800 rounded-2xl shadow-md p-6 hover:shadow-lg transition">
<!-- Badge -->
<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 -->
<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" />
<!-- Responsive nav (mobile stack → desktop row) -->
<nav class="flex flex-col md:flex-row gap-2 md:gap-6">
| 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 |
Source: Bhat — Ultimate Tailwind CSS Handbook (BPB, 2023)
data-ai
Use when adding AI-powered analytics to a SaaS platform — semantic search over business data, natural language queries, trend detection, anomaly alerts, and AI-generated insights for dashboards. Covers embeddings, NL2SQL, and per-tenant analytics...
data-ai
Design AI-powered analytics dashboards — what metrics to show, how to display AI predictions and confidence, drill-down patterns, KPI cards, trend visualisation, AI Insights panels, export design, and role-based dashboard variants. Invoke when...
development
Use when designing, building, reviewing, or upgrading production software systems that must be secure, performant, maintainable, scalable, and user-centered. Apply before writing specs, code, architecture, APIs, databases, mobile apps, SaaS platforms, or ERP systems.
development
Professional web app UI using commercial templates (Tabler/Bootstrap 5) with strong frontend design direction when needed. Use for CRUD interfaces, dashboards, admin panels with SweetAlert2, DataTables, Flatpickr. Clone seeder-page.php, use...