
Tailwind
- 521 installs
- 191 repo stars
- Updated July 24, 2026
- pproenca/dot-skills
tailwind is an agent skill that applies 44 Tailwind CSS v4 performance and best-practice rules for developers who write, review, or refactor utility-first frontend code.
About
tailwind is a curated Agent Skills package from pproenca/dot-skills that encodes Tailwind CSS v4 performance optimization and best-practice guidance for coding agents. The skill bundles 44 rules organized across 8 impact-prioritized categories, with AGENTS.md as the compiled reference and metadata.json for version tracking. Agents load it when tasks touch Tailwind configuration, the @theme directive, utility classes, responsive design, dark mode, container queries, or CSS output size. It steers code generation and refactors toward minimal generated CSS, correct v4 feature usage, and faster builds with Vite, PostCSS, or the Tailwind CLI. Developers reach for tailwind when shipping or reviewing Tailwind-heavy React, Next.js, or static sites and need consistent v4 conventions without re-reading upstream docs each session. Install via npx skills add pproenca/dot-skills --skill tailwind. Reference files include assets/templates/_template.md for extending rules and flags costly @apply overuse, redundant PostCSS plugins, and excessive theme variables during reviews.
- tailwind
Tailwind by the numbers
- 521 all-time installs (skills.sh)
- +14 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #767 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/pproenca/dot-skills --skill tailwindAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 521 |
|---|---|
| repo stars | ★ 191 |
| Last updated | July 24, 2026 |
| Repository | pproenca/dot-skills ↗ |
How do you optimize Tailwind CSS v4 for performance?
Use tailwind for development tasks
Who is it for?
Frontend developers maintaining Tailwind CSS v4 apps who want agents to enforce performance rules during edits and reviews.
Skip if: Teams on Tailwind v3-only stacks or projects that do not use utility-first CSS should skip tailwind.
When should I use this skill?
User edits Tailwind config, @theme, utilities, responsive breakpoints, dark mode, or asks to reduce CSS bundle size.
What you get
Refactored Tailwind v4 components, leaner CSS bundles, and AGENTS.md-aligned configuration patterns.
- Optimized utility-class components
- Tailwind v4 configuration guidance
- CSS bundle-size recommendations
By the numbers
- Bundles 44 Tailwind CSS v4 rules across 8 categories
- Includes AGENTS.md, references/_sections.md, and metadata.json reference files
Files
Community Tailwind CSS v4 Best Practices
Comprehensive performance optimization guide for Tailwind CSS v4 applications. Contains 44 rules across 8 categories, prioritized by impact to guide automated refactoring and code generation.
When to Apply
Reference these guidelines when:
- Configuring Tailwind CSS v4 build tooling (Vite plugin, PostCSS, CLI)
- Writing or migrating styles using v4's CSS-first approach
- Optimizing CSS bundle size and build performance
- Implementing responsive designs with breakpoints or container queries
- Setting up theming with @theme directive and design tokens
Rule Categories by Priority
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Build Configuration | CRITICAL | build- |
| 2 | CSS Generation | CRITICAL | gen- |
| 3 | Bundle Optimization | HIGH | bundle- |
| 4 | Utility Patterns | HIGH | util- |
| 5 | Component Architecture | MEDIUM-HIGH | comp- |
| 6 | Theming & Design Tokens | MEDIUM | theme- |
| 7 | Responsive & Adaptive | MEDIUM | resp- |
| 8 | Animation & Transitions | LOW-MEDIUM | anim- |
Quick Reference
1. Build Configuration (CRITICAL)
- `build-vite-plugin` - Use Vite Plugin Over PostCSS
- `build-css-import` - Use CSS Import Over @tailwind Directives
- `build-content-detection` - Leverage Automatic Content Detection
- `build-node-version` - Use Node.js 20+ for Optimal Performance
- `build-postcss-simplify` - Remove Redundant PostCSS Plugins
- `build-cli-package` - Use Correct CLI Package
2. CSS Generation (CRITICAL)
- `gen-css-first-config` - Use CSS-First Configuration Over JavaScript
- `gen-avoid-theme-bloat` - Avoid Excessive Theme Variables
- `gen-oklch-colors` - Use OKLCH Color Space for Vivid Colors
- `gen-utility-directive` - Use @utility for Custom Utilities
- `gen-dynamic-utilities` - Use Dynamic Utility Values
- `gen-css-variable-syntax` - Use Parentheses for CSS Variable References
3. Bundle Optimization (HIGH)
- `bundle-remove-unused-plugins` - Remove Built-in Plugins
- `bundle-avoid-preprocessors` - Avoid Sass/Less Preprocessors
- `bundle-css-minification` - Enable CSS Minification in Production
- `bundle-avoid-cdn-production` - Avoid Play CDN in Production
- `bundle-split-critical-css` - Extract Critical CSS for Initial Render
4. Utility Patterns (HIGH)
- `util-renamed-utilities` - Use Renamed Utility Classes
- `util-important-modifier` - Use Trailing Important Modifier
- `util-variant-stacking` - Use Left-to-Right Variant Stacking
- `util-explicit-colors` - Use Explicit Border and Ring Colors
- `util-opacity-modifier` - Use Slash Opacity Modifier
- `util-gradient-via-none` - Use via-none to Reset Gradient Stops
5. Component Architecture (MEDIUM-HIGH)
- `comp-avoid-apply-overuse` - Avoid Overusing @apply
- `comp-reference-directive` - Use @reference for CSS Module Integration
- `comp-utility-file-scope` - Understand Utility File Scope
- `comp-smart-sorting` - Leverage Smart Utility Sorting
- `comp-container-customize` - Customize Container with @utility
- `comp-custom-variant` - Use @custom-variant for Custom Variant Definitions
6. Theming & Design Tokens (MEDIUM)
- `theme-semantic-tokens` - Use Semantic Design Token Names
- `theme-dark-mode-class` - Use Class-Based Dark Mode for Control
- `theme-prefix-variables` - Use Prefix for Variable Namespacing
- `theme-runtime-variables` - Leverage Runtime CSS Variables
- `theme-color-scheme` - Set color-scheme for Native Dark Mode
- `theme-inline-static` - Use @theme inline and @theme static for Variable Control
7. Responsive & Adaptive (MEDIUM)
- `resp-mobile-first` - Use Mobile-First Responsive Design
- `resp-container-queries` - Use Container Queries for Component-Level Responsiveness
- `resp-custom-breakpoints` - Define Custom Breakpoints in @theme
- `resp-hover-capability` - Pair Hover with Active for Touch-Friendly Interactions
- `resp-logical-properties` - Use Logical Properties for RTL Support
8. Animation & Transitions (LOW-MEDIUM)
- `anim-gpu-accelerated` - Use GPU-Accelerated Transform Properties
- `anim-starting-style` - Use @starting-style for Entry Animations
- `anim-gradient-interpolation` - Use OKLCH Gradient Interpolation
- `anim-3d-transforms` - Use Built-in 3D Transform Utilities
How to Use
Read individual reference files for detailed explanations and code examples:
- Section definitions - Category structure and impact levels
- Rule template - Template for adding new rules
Full Compiled Document
For a complete guide with all rules expanded, see AGENTS.md.
Reference Files
| File | Description |
|---|---|
| AGENTS.md | Complete compiled guide with all rules |
| references/_sections.md | Category definitions and ordering |
| assets/templates/_template.md | Template for new rules |
| metadata.json | Version and reference information |
Tailwind CSS v4
Version 1.0.0 Community January 2026
Note:
This Tailwind CSS v4 document is mainly for agents and LLMs to follow when maintaining,
generating, or refactoring codebases. Humans may also find it useful,
but guidance here is optimized for automation and consistency by AI-assisted workflows.
---
Abstract
Comprehensive performance optimization and best practices guide for Tailwind CSS v4, designed for AI agents and LLMs. Contains 44 rules across 8 categories, prioritized by impact from critical (build configuration, CSS generation) to incremental (animation patterns). Each rule includes detailed explanations, real-world examples comparing incorrect vs. correct implementations, and specific impact metrics to guide automated refactoring and code generation.
---
Table of Contents
1. Build Configuration — CRITICAL
- 1.1 Leverage Automatic Content Detection — CRITICAL (eliminates manual configuration, prevents missing utilities)
- 1.2 Remove Redundant PostCSS Plugins — HIGH (reduces plugin overhead, simplifies configuration)
- 1.3 Use Correct CLI Package — HIGH (prevents build failures, ensures v4 compatibility)
- 1.4 Use CSS Import Over @tailwind Directives — CRITICAL (eliminates deprecated patterns, enables v4 features)
- 1.5 Use Node.js 20+ for Optimal Performance — MEDIUM (required for upgrade tool, enables modern optimizations)
- 1.6 Use Vite Plugin Over PostCSS — CRITICAL (2-5x faster HMR and incremental performance vs PostCSS)
2. CSS Generation — CRITICAL
- 2.1 Avoid Excessive Theme Variables — MEDIUM (reduces design token clutter and CSS variable declarations)
- 2.2 Use @utility for Custom Utilities — HIGH (enables variant support, proper sorting)
- 2.3 Use CSS-First Configuration Over JavaScript — CRITICAL (single source of truth, eliminates config file overhead)
- 2.4 Use Dynamic Utility Values — HIGH (eliminates arbitrary value syntax, cleaner markup)
- 2.5 Use OKLCH Color Space for Vivid Colors — HIGH (20-30% wider color gamut, perceptually uniform)
- 2.6 Use Parentheses for CSS Variable References — MEDIUM-HIGH (required v4 syntax, prevents build errors)
3. Bundle Optimization — HIGH
- 3.1 Avoid Play CDN in Production — HIGH (10-100× larger payload, runtime compilation overhead)
- 3.2 Avoid Sass/Less Preprocessors — HIGH (prevents compatibility issues, enables native features)
- 3.3 Enable CSS Minification in Production — HIGH (40-60% smaller CSS bundles)
- 3.4 Extract Critical CSS for Initial Render — MEDIUM-HIGH (100-300ms faster FCP on slow connections)
- 3.5 Remove Built-in Plugins — HIGH (eliminates duplicate code, reduces dependencies)
4. Utility Patterns — HIGH
- 4.1 Use Explicit Border and Ring Colors — HIGH (prevents invisible borders, ensures consistent appearance)
- 4.2 Use Left-to-Right Variant Stacking — HIGH (prevents broken responsive/state styles)
- 4.3 Use Renamed Utility Classes — HIGH (prevents broken styles, ensures v4 compatibility)
- 4.4 Use Slash Opacity Modifier — HIGH (50% fewer opacity-related classes)
- 4.5 Use Trailing Important Modifier — HIGH (prevents v4 syntax errors)
- 4.6 Use via-none to Reset Gradient Stops — MEDIUM-HIGH (prevents unexpected gradient behavior with variants)
5. Component Architecture — MEDIUM-HIGH
- 5.1 Avoid Overusing @apply — MEDIUM-HIGH (prevents CSS bloat, maintains utility-first benefits)
- 5.2 Customize Container with @utility — MEDIUM (prevents v4 migration breakage)
- 5.3 Leverage Smart Utility Sorting — MEDIUM (automatic cascade ordering, fewer specificity issues)
- 5.4 Understand Utility File Scope — MEDIUM-HIGH (prevents build errors and missing class bugs)
- 5.5 Use @reference for CSS Module Integration — MEDIUM-HIGH (eliminates duplicate CSS output in modules)
- 5.6 Use @custom-variant for Custom Variant Definitions — MEDIUM-HIGH (enables reusable custom variants without JavaScript plugins)
6. Theming & Design Tokens — MEDIUM
- 6.1 Leverage Runtime CSS Variables — MEDIUM (enables dynamic theming without JavaScript)
- 6.2 Set color-scheme for Native Dark Mode — MEDIUM (eliminates visual theme inconsistencies)
- 6.3 Use Class-Based Dark Mode for Control — MEDIUM (enables manual theme switching, better user control)
- 6.4 Use Prefix for Variable Namespacing — MEDIUM (prevents CSS variable conflicts in large codebases)
- 6.5 Use Semantic Design Token Names — MEDIUM (improves maintainability, enables theme switching)
- 6.6 Use @theme inline and @theme static for Variable Control — MEDIUM (controls CSS variable generation, reduces runtime overhead)
7. Responsive & Adaptive — MEDIUM
- 7.1 Define Custom Breakpoints in @theme — MEDIUM (enables project-specific responsive design)
- 7.2 Pair Hover with Active for Touch-Friendly Interactions — MEDIUM (prevents missing feedback on touch devices)
- 7.3 Use Container Queries for Component-Level Responsiveness — MEDIUM (eliminates viewport-dependent component bugs)
- 7.4 Use Logical Properties for RTL Support — MEDIUM (automatic RTL support without duplicate styles)
- 7.5 Use Mobile-First Responsive Design — MEDIUM (10-30% smaller CSS output)
8. Animation & Transitions — LOW-MEDIUM
- 8.1 Use @starting-style for Entry Animations — LOW-MEDIUM (enables CSS-only entry animations, no JavaScript)
- 8.2 Use Built-in 3D Transform Utilities — LOW-MEDIUM (enables 3D effects without custom CSS)
- 8.3 Use GPU-Accelerated Transform Properties — LOW-MEDIUM (60fps animations, avoids layout thrashing)
- 8.4 Use OKLCH Gradient Interpolation — LOW-MEDIUM (20-40% more vivid gradient midpoints)
---
References
1. https://tailwindcss.com/docs 2. https://tailwindcss.com/blog/tailwindcss-v4 3. https://tailwindcss.com/docs/upgrade-guide 4. https://tailwindcss.com/docs/functions-and-directives 5. https://tailwindcss.com/docs/theme 6. https://github.com/tailwindlabs/tailwindcss
---
Source Files
This document was compiled from individual reference files. For detailed editing or extension:
| File | Description |
|---|---|
| references/_sections.md | Category definitions and impact ordering |
| assets/templates/_template.md | Template for creating new rules |
| SKILL.md | Quick reference entry point |
| metadata.json | Version and reference URLs |
{Rule Title}
{1-3 sentences explaining WHY this matters. Focus on performance implications.}
Incorrect ({what's wrong}):
```{language} {Bad code example - production-realistic, not strawman} {// Comments explaining the cost}
**Correct ({what's right}):**
{Good code example - minimal diff from incorrect} {// Comments explaining the benefit}
{Optional sections as needed:}
**Alternative ({context}):**
{Alternative approach when applicable}
**When NOT to use this pattern:**
- {Exception 1}
- {Exception 2}
**Benefits:**
- {Benefit 1}
- {Benefit 2}
Reference: [{Reference Title}]({Reference URL})
{
"version": "1.0.6",
"organization": "Community",
"technology": "Tailwind CSS v4",
"date": "January 2026",
"abstract": "Comprehensive performance optimization and best practices guide for Tailwind CSS v4, designed for AI agents and LLMs. Contains 44 rules across 8 categories, prioritized by impact from critical (build configuration, CSS generation) to incremental (animation patterns). Each rule includes detailed explanations, real-world examples comparing incorrect vs. correct implementations, and specific impact metrics to guide automated refactoring and code generation.",
"references": [
"https://tailwindcss.com/docs",
"https://tailwindcss.com/blog/tailwindcss-v4",
"https://tailwindcss.com/docs/upgrade-guide",
"https://tailwindcss.com/docs/functions-and-directives",
"https://tailwindcss.com/docs/theme",
"https://github.com/tailwindlabs/tailwindcss"
],
"category": "Frontend"
}
Tailwind CSS v4 Best Practices Skill
A comprehensive performance optimization and best practices guide for Tailwind CSS v4, designed for AI agents and LLMs.
Overview
This skill contains 42 rules across 8 categories, covering:
- Build configuration and tooling optimization
- CSS generation and @theme directive usage
- Bundle size optimization
- Utility class patterns and v4 syntax changes
- Component architecture and @apply best practices
- Theming and design tokens
- Responsive design and container queries
- Animation and transition performance
Structure
tailwindcss-v4-style/
├── SKILL.md # Entry point with quick reference
├── AGENTS.md # Compiled comprehensive guide
├── metadata.json # Version, organization, references
├── README.md # This file
├── references/
│ ├── _sections.md # Category definitions
│ ├── build-*.md # Build configuration rules (6)
│ ├── gen-*.md # CSS generation rules (6)
│ ├── bundle-*.md # Bundle optimization rules (5)
│ ├── util-*.md # Utility pattern rules (6)
│ ├── comp-*.md # Component architecture rules (5)
│ ├── theme-*.md # Theming rules (5)
│ ├── resp-*.md # Responsive design rules (5)
│ └── anim-*.md # Animation rules (4)
└── assets/
└── templates/
└── _template.md # Rule template for extensionsGetting Started
Installation
# Install dependencies
pnpm install
# Build the compiled AGENTS.md
pnpm build
# Validate the skill
pnpm validateUsage
Reference this skill when working with Tailwind CSS v4 projects. The rules are organized by impact level:
1. CRITICAL - Build configuration and CSS generation (address first) 2. HIGH - Bundle optimization and utility patterns 3. MEDIUM-HIGH - Component architecture 4. MEDIUM - Theming and responsive design 5. LOW-MEDIUM - Animation and transitions
Creating a New Rule
1. Choose the appropriate category and prefix from the table below 2. Create a new file: references/{prefix}-{description}.md 3. Use the template from assets/templates/_template.md 4. Run validation to ensure compliance
Prefix Reference
| Category | Prefix | Impact |
|---|---|---|
| Build Configuration | build- | CRITICAL |
| CSS Generation | gen- | CRITICAL |
| Bundle Optimization | bundle- | HIGH |
| Utility Patterns | util- | HIGH |
| Component Architecture | comp- | MEDIUM-HIGH |
| Theming & Design Tokens | theme- | MEDIUM |
| Responsive & Adaptive | resp- | MEDIUM |
| Animation & Transitions | anim- | LOW-MEDIUM |
Rule File Structure
---
title: Rule Title
impact: CRITICAL|HIGH|MEDIUM-HIGH|MEDIUM|LOW-MEDIUM|LOW
impactDescription: Quantified impact (e.g., "2-10× improvement")
tags: prefix, technique, tool, related-concepts
---
## Rule Title
Brief explanation of WHY this matters (1-3 sentences).
**Incorrect (problem description):**
\`\`\`language
// Bad code example
\`\`\`
**Correct (solution description):**
\`\`\`language
// Good code example
\`\`\`
Reference: [Title](URL)File Naming Convention
Rule files follow the pattern: {prefix}-{descriptive-slug}.md
Examples:
build-vite-plugin.mdgen-css-first-config.mdutil-renamed-utilities.md
Impact Levels
| Level | Description |
|---|---|
| CRITICAL | Must fix immediately; 5-100× performance impact |
| HIGH | Address in current sprint; 2-10× impact |
| MEDIUM-HIGH | Address soon; measurable improvement |
| MEDIUM | Address when convenient; noticeable improvement |
| LOW-MEDIUM | Address if time permits; minor optimization |
| LOW | Nice to have; minimal impact |
Scripts
# Build AGENTS.md from references
pnpm build
# Validate skill structure and content
pnpm validate
# Validate with strict mode
pnpm validate --strictContributing
1. Read existing rules in the same category for style consistency 2. Follow the minimal diff philosophy (incorrect/correct examples should be nearly identical) 3. Quantify impact where possible 4. Include authoritative references 5. Run validation before submitting
Acknowledgments
Based on official Tailwind CSS v4 documentation and best practices from:
Sections
This file defines all sections, their ordering, impact levels, and descriptions. The section ID (in parentheses) is the filename prefix used to group rules.
---
1. Build Configuration (build)
Impact: CRITICAL Description: Build tooling decisions cascade through the entire pipeline. Vite plugin vs PostCSS, content detection, and configuration approach determine baseline performance with 5-100× build time differences.
2. CSS Generation (gen)
Impact: CRITICAL Description: How utilities are generated affects bundle size by 2-10×. @theme overuse, duplicate utilities, and JIT inefficiencies bloat CSS output and slow browser parsing.
3. Bundle Optimization (bundle)
Impact: HIGH Description: CSS delivery impacts Core Web Vitals directly. Unused styles, missing compression, and suboptimal code splitting delay LCP and FCP by 100-500ms.
4. Utility Patterns (util)
Impact: HIGH Description: Choosing correct utilities prevents layout thrashing and repaints. Class ordering, responsive variants, and utility composition affect browser rendering work.
5. Component Architecture (comp)
Impact: MEDIUM-HIGH Description: How styles are organized in components affects maintainability and runtime performance. @apply misuse, extraction patterns, and variant usage impact both bundle size and DX.
6. Theming & Design Tokens (theme)
Impact: MEDIUM Description: @theme directive usage, CSS variable organization, and dark mode implementation affect bundle size, runtime flexibility, and cascade layer efficiency.
7. Responsive & Adaptive (resp)
Impact: MEDIUM Description: Breakpoint strategies, container queries, and adaptive patterns impact layout performance and CSS complexity. Mobile-first vs desktop-first affects generated CSS size.
8. Animation & Transitions (anim)
Impact: LOW-MEDIUM Description: GPU-accelerated vs layout-triggering animations, transition utilities, and @starting-style usage affect paint performance and visual smoothness.
Use Built-in 3D Transform Utilities
Tailwind CSS v4 includes native 3D transform utilities. Use them instead of arbitrary values for perspective, 3D rotations, and transform styles.
Incorrect (arbitrary 3D values):
<div class="[perspective:1000px]">
<div class="[transform-style:preserve-3d] [rotate-x:45deg] [rotate-z:30deg]">
<!-- Arbitrary syntax for 3D transforms -->
</div>
</div>Correct (native 3D utilities):
<div class="perspective-distant">
<article class="transform-3d rotate-x-45 rotate-z-30">
<!-- Native 3D transform utilities -->
</article>
</div>Available 3D utilities:
<!-- Perspective on container -->
<div class="perspective-dramatic"> <!-- 100px -->
<div class="perspective-near"> <!-- 300px -->
<div class="perspective-normal"> <!-- 500px -->
<div class="perspective-midrange"> <!-- 800px -->
<div class="perspective-distant"> <!-- 1200px -->
<!-- 3D transform style -->
<div class="transform-3d"> <!-- preserve-3d -->
<div class="transform-flat"> <!-- flat -->
<!-- 3D rotations -->
<div class="rotate-x-45"> <!-- rotateX(45deg) -->
<div class="rotate-y-90"> <!-- rotateY(90deg) -->
<div class="rotate-z-180"> <!-- rotateZ(180deg) -->
<!-- Backface visibility -->
<div class="backface-visible">
<div class="backface-hidden">Reference: Tailwind CSS v4.0 Release
Use GPU-Accelerated Transform Properties
Animate transform and opacity properties instead of layout-triggering properties like width, height, top, or left. GPU-accelerated properties don't trigger layout recalculation.
Incorrect (layout-triggering animation):
<div class="transition-all duration-300 w-20 hover:w-40">
<!-- Animating width triggers layout on every frame -->
</div>
<div class="absolute top-0 hover:top-10 transition-all">
<!-- Animating top triggers layout recalculation -->
</div>Correct (GPU-accelerated animation):
<div class="transition-transform duration-300 scale-100 hover:scale-x-150">
<!-- Transform is GPU-accelerated, no layout triggers -->
</div>
<div class="absolute transition-transform hover:translate-y-10">
<!-- Translate is GPU-accelerated -->
</div>GPU-accelerated properties:
transform(translate, rotate, scale, skew)opacityfilter(blur, brightness, etc.)
Layout-triggering properties (avoid animating):
width,heighttop,right,bottom,leftmargin,paddingfont-size
Reference: Tailwind CSS v4.0 Release
Use OKLCH Gradient Interpolation
Use the /oklch modifier for gradient interpolation to produce more vivid colors and avoid muddy midpoints that occur with sRGB interpolation.
Incorrect (default sRGB interpolation):
<div class="bg-linear-to-r from-blue-500 to-green-500">
<!-- sRGB interpolation produces grayish/muddy midpoint -->
</div>Correct (OKLCH interpolation):
<div class="bg-linear-to-r/oklch from-blue-500 to-green-500">
<!-- OKLCH produces vibrant cyan midpoint -->
</div>Interpolation comparison:
<!-- sRGB: Colors can look desaturated in the middle -->
<div class="h-10 bg-linear-to-r/srgb from-red-500 to-blue-500"></div>
<!-- OKLCH: Maintains vibrance throughout -->
<div class="h-10 bg-linear-to-r/oklch from-red-500 to-blue-500"></div>
<!-- Longer hue path for rainbow effect -->
<div class="h-10 bg-linear-to-r/[in_oklch_longer_hue] from-red-500 to-red-500"></div>When to use OKLCH:
- Gradients between complementary colors
- Brand gradients requiring specific midpoints
- Any gradient where sRGB looks "muddy"
Reference: Tailwind CSS v4.0 Release
Use @starting-style for Entry Animations
Use the starting: variant for CSS-only entry animations on elements that appear dynamically (popovers, dialogs, conditionally rendered elements).
Incorrect (JavaScript-dependent animation):
function Popover({ isOpen }) {
return (
<div
className={`transition-opacity duration-200 ${
isOpen ? "opacity-100" : "opacity-0"
}`}
>
{/* Requires JavaScript state management */}
</div>
);
}Correct (CSS-only with @starting-style):
<button popovertarget="my-popover">Open</button>
<div
popover
id="my-popover"
class="transition-discrete opacity-100 starting:open:opacity-0"
>
<!-- Animates from 0 to 100% opacity when popover opens -->
<!-- No JavaScript required -->
</div>With scale and translate:
<div
popover
id="menu"
class="
transition-discrete
opacity-100 scale-100 translate-y-0
starting:open:opacity-0
starting:open:scale-95
starting:open:translate-y-2
"
>
<!-- Fades in, scales up, and slides down -->
</div>Note: transition-discrete is required for animating display property changes.
Reference: Tailwind CSS v4.0 Release
Use Correct CLI Package
Tailwind CSS v4 uses a separate CLI package. Using the old CLI command with v4 will cause build failures.
Incorrect (v3 CLI command):
# Old CLI - incompatible with v4
npx tailwindcss -i input.css -o output.css
# Results in missing utilities or errorsCorrect (v4 CLI package):
# New CLI package for v4
npx @tailwindcss/cli -i input.css -o output.css{
"scripts": {
"build:css": "tailwindcss -i ./src/input.css -o ./dist/output.css"
},
"devDependencies": {
"@tailwindcss/cli": "^4.0.0"
}
}Note: If using Vite or PostCSS integration, you typically don't need the CLI at all.
Reference: Tailwind CSS Installation
Leverage Automatic Content Detection
Tailwind CSS v4 automatically detects template files without manual configuration. Only use @source when you need to include files outside the standard detection scope.
Incorrect (unnecessary manual configuration):
/* styles.css */
@import "tailwindcss";
/* Redundant - these paths are auto-detected */
@source "./src/**/*.{js,ts,jsx,tsx}";
@source "./components/**/*.vue";
@source "./app/**/*.tsx";Correct (minimal configuration):
/* styles.css */
@import "tailwindcss";
/* Only specify external packages not in your repo */
@source "../node_modules/@my-company/ui-lib";When to use @source:
- External UI libraries in node_modules
- Files outside the project root
- Paths excluded by .gitignore that you need to include
Auto-ignored paths:
- Files listed in .gitignore
- Binary files (images, videos, zips)
- node_modules (unless explicitly sourced)
Reference: Tailwind CSS Functions and Directives
Use CSS Import Over @tailwind Directives
Tailwind CSS v4 replaces the old @tailwind directives with a single CSS import statement. This enables automatic content detection and modern CSS features.
Incorrect (v3 deprecated directives):
/* styles.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Requires explicit content configuration */Correct (v4 CSS import):
/* styles.css */
@import "tailwindcss";
/* Automatic content detection, zero configuration */Benefits:
- Zero configuration required for most projects
- Automatic template file detection
- Built-in @import support without additional plugins
- Single source of truth for styles
Reference: Tailwind CSS Upgrade Guide
Use Node.js 20+ for Optimal Performance
Tailwind CSS v4 and its upgrade tool require Node.js 20 or higher. Older Node versions may cause build failures or suboptimal performance.
Incorrect (outdated Node version):
{
"engines": {
"node": ">=16.0.0"
}
}# Node 16/18 may cause issues
npx @tailwindcss/upgrade
# Error: Requires Node.js 20+Correct (modern Node version):
{
"engines": {
"node": ">=20.0.0"
}
}# Node 20+ runs optimally
npx @tailwindcss/upgrade
# Upgrade completes successfullyBenefits:
- Full compatibility with Tailwind v4 tooling
- Better performance from V8 engine improvements
- Access to modern JavaScript features
- Required for automated migration
Reference: Tailwind CSS Upgrade Guide
Remove Redundant PostCSS Plugins
Tailwind CSS v4's @tailwindcss/postcss plugin includes functionality that previously required separate plugins. Remove redundant plugins to simplify configuration and reduce build overhead.
Incorrect (redundant plugins):
// postcss.config.js
export default {
plugins: [
"postcss-import", // Now built-in
"tailwindcss/nesting", // Now built-in
"@tailwindcss/postcss",
"autoprefixer", // Now built-in
],
};Correct (simplified configuration):
// postcss.config.js
export default {
plugins: ["@tailwindcss/postcss"],
};Built-in functionality in v4:
@importprocessing (no postcss-import needed)- CSS nesting (no tailwindcss/nesting needed)
- Vendor prefixing (no autoprefixer needed)
Reference: Tailwind CSS Upgrade Guide
Use Vite Plugin Over PostCSS
The first-party Vite plugin provides tighter integration and better performance than the PostCSS plugin, especially for Hot Module Replacement and incremental rebuilds during development.
Incorrect (PostCSS approach in Vite projects):
// postcss.config.js — works, but misses Vite-specific optimizations
export default {
plugins: ["@tailwindcss/postcss"],
};Correct (dedicated Vite plugin):
// vite.config.ts
import { defineConfig } from "vite";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
plugins: [tailwindcss()],
});When NOT to use this pattern:
- Projects not using Vite as their build tool
- Projects using webpack, Parcel, or other bundlers (use
@tailwindcss/postcssinstead)
Note: Both integration methods benefit from v4's engine improvements (full builds up to 5x faster, incremental builds over 100x faster than v3). The Vite plugin adds further gains through direct bundler integration.
Reference: Tailwind CSS v4.0 Release
Avoid Play CDN in Production
The Play CDN is designed for prototyping and learning. It compiles Tailwind in the browser, resulting in significant performance overhead.
Incorrect (CDN in production):
<!DOCTYPE html>
<html>
<head>
<!-- Runtime compilation in browser -->
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
</head>
<body>
<div class="bg-blue-500 p-4">
<!-- Every page load recompiles styles -->
</div>
</body>
</html>Correct (build-time compilation):
<!DOCTYPE html>
<html>
<head>
<!-- Pre-compiled, minified CSS -->
<link href="/dist/styles.css" rel="stylesheet">
</head>
<body>
<div class="bg-blue-500 p-4">
<!-- Zero runtime overhead -->
</div>
</body>
</html>Play CDN is appropriate for:
- Quick prototypes and demos
- CodePen/JSFiddle examples
- Learning and experimentation
Never use CDN for:
- Production websites
- Performance-critical applications
- SEO-sensitive pages
Reference: Tailwind CSS Play CDN
Avoid Sass/Less Preprocessors
Tailwind CSS v4 is incompatible with Sass, Less, and Stylus preprocessors. Modern CSS and Tailwind's built-in features replace the need for these tools.
Incorrect (preprocessor syntax):
// styles.scss
@import "tailwindcss"; // May fail with preprocessor
.navigation {
$spacing: 1rem;
padding: $spacing;
&__item {
color: $brand-color;
&:hover {
color: darken($brand-color, 10%);
}
}
}Correct (native CSS with Tailwind):
/* styles.css */
@import "tailwindcss";
.navigation {
padding: var(--spacing-4);
&__item {
color: var(--color-brand);
&:hover {
color: oklch(from var(--color-brand) calc(l - 0.1) c h);
}
}
}Native CSS alternatives:
- CSS nesting (built into v4)
- CSS custom properties (replace Sass variables)
@themedirective (replace Sass maps)calc()and modern CSS functionsoklch(from ...)relative color syntax (replace Sassdarken/lighten)
Reference: Tailwind CSS Upgrade Guide
Enable CSS Minification in Production
Ensure CSS minification is enabled for production builds. While Tailwind's JIT produces minimal CSS, minification removes whitespace and optimizes output further.
Incorrect (no minification):
// vite.config.ts
import { defineConfig } from "vite";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
plugins: [tailwindcss()],
build: {
cssMinify: false, // Disabled minification
},
});Correct (minification enabled):
// vite.config.ts
import { defineConfig } from "vite";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
plugins: [tailwindcss()],
build: {
cssMinify: "lightningcss", // Fast, modern minifier
},
});For CLI builds:
# Development (readable output)
npx @tailwindcss/cli -i input.css -o output.css
# Production (minified)
npx @tailwindcss/cli -i input.css -o output.css --minifyBenefits:
- 40-60% smaller file sizes
- Faster network transfer
- Improved Core Web Vitals
Reference: Tailwind CSS Installation
Remove Built-in Plugins
Tailwind CSS v4 includes features that previously required separate plugins. Remove these plugins to avoid duplicate code and reduce bundle size.
Incorrect (unnecessary plugins):
{
"devDependencies": {
"tailwindcss": "^4.0.0",
"@tailwindcss/container-queries": "^0.1.0",
"@tailwindcss/aspect-ratio": "^0.4.0"
}
}/* Duplicate functionality */
@import "@tailwindcss/container-queries";Correct (use built-in features):
{
"devDependencies": {
"tailwindcss": "^4.0.0"
}
}<!-- Container queries are built-in -->
<div class="@container">
<div class="@sm:grid-cols-3 @lg:grid-cols-4">Content</div>
</div>
<!-- Aspect ratio is built-in -->
<div class="aspect-video">Video</div>Built-in features in v4:
- Container queries (
@container,@sm:,@lg:) - Aspect ratio utilities
- Logical properties
- 3D transforms
Reference: Tailwind CSS v4.0 Release
Extract Critical CSS for Initial Render
For large applications, extract critical CSS for above-the-fold content to improve First Contentful Paint (FCP). Most modern frameworks handle this automatically.
Incorrect (single render-blocking stylesheet):
<head>
<!-- Blocks rendering until fully loaded -->
<link href="/styles.css" rel="stylesheet">
</head>Correct (critical CSS inlined with async loading):
<head>
<!-- Critical styles inline for immediate render -->
<style>/* Generated by build tool — above-the-fold styles */</style>
<!-- Full stylesheet loads async -->
<link href="/styles.css" rel="stylesheet" media="print" onload="this.media='all'">
<noscript><link href="/styles.css" rel="stylesheet"></noscript>
</head>Framework-specific solutions:
// Next.js — automatically inlines critical CSS with App Router
// No manual configuration needed
// Vite — use vite-plugin-critical or critters
import critical from "vite-plugin-critical";
export default defineConfig({
plugins: [
tailwindcss(),
critical({ criticalUrl: "http://localhost:3000" }),
],
});When to use:
- Large CSS bundles (>50KB)
- Slow network connections matter (3G users)
- FCP is a critical metric
- Framework doesn't handle it automatically
Note: Many modern frameworks (Next.js App Router, Nuxt, SvelteKit) handle critical CSS extraction automatically. Check your framework's docs before adding manual tooling.
Reference: Tailwind CSS Optimizing for Production
Avoid Overusing @apply
While @apply extracts utility patterns into custom classes, overuse defeats the purpose of utility-first CSS. Use it sparingly for small, highly reusable patterns.
Incorrect (over-abstraction):
/* Recreating traditional CSS with extra steps */
@utility card {
@apply bg-white rounded-lg shadow-md p-6 border border-gray-200;
}
@utility card-header {
@apply text-xl font-bold text-gray-900 mb-4;
}
@utility card-body {
@apply text-gray-600 leading-relaxed;
}
@utility card-footer {
@apply mt-4 pt-4 border-t border-gray-200 flex justify-end gap-2;
}
/* Now you have to manage class names AND jump between files */Correct (utility-first with components):
// Card.tsx - Component handles abstraction
function Card({ children, className }) {
return (
<div className={`bg-white rounded-lg shadow-md p-6 border border-gray-200 ${className}`}>
{children}
</div>
);
}
// Usage
<Card className="hover:shadow-lg">
<h2 className="text-xl font-bold text-gray-900 mb-4">Title</h2>
<p className="text-gray-600 leading-relaxed">Content</p>
</Card>When @apply is appropriate:
- Tiny, repeated patterns (buttons, badges)
- Third-party component styling you can't control
- Base form element resets
Reference: Tailwind CSS Reusing Styles
Customize Container with @utility
Tailwind CSS v4 removes the container configuration options (center, padding). Customize the container utility using @utility instead.
Incorrect (v3 configuration):
// tailwind.config.js - No longer works in v4
module.exports = {
theme: {
container: {
center: true,
padding: "2rem",
},
},
};Correct (v4 @utility customization):
@import "tailwindcss";
@utility container {
margin-inline: auto;
padding-inline: 2rem;
}With responsive padding:
@utility container {
margin-inline: auto;
padding-inline: 1rem;
@media (width >= 640px) {
padding-inline: 2rem;
}
@media (width >= 1024px) {
padding-inline: 4rem;
}
}Benefits:
- Full CSS control over container behavior
- Responsive customization without config
- Consistent with CSS-first approach
Reference: Tailwind CSS Upgrade Guide
Use @custom-variant for Custom Variant Definitions
Use the @custom-variant directive to define custom variants directly in CSS, replacing the need for JavaScript plugins. Custom variants work with all utility classes just like built-in variants.
Incorrect (JavaScript plugin for custom variant):
// tailwind.config.js — v3 approach
const plugin = require("tailwindcss/plugin");
module.exports = {
plugins: [
plugin(function ({ addVariant }) {
addVariant("theme-midnight", "&:where([data-theme='midnight'] *)");
addVariant("sidebar-open", "&:where([data-sidebar='open'] *)");
}),
],
};Correct (CSS-first with @custom-variant):
/* styles.css */
@import "tailwindcss";
@custom-variant theme-midnight (&:where([data-theme="midnight"] *));
@custom-variant sidebar-open (&:where([data-sidebar="open"] *));<div data-theme="midnight">
<p class="text-gray-900 theme-midnight:text-white">
Adapts to midnight theme
</p>
</div>
<nav class="w-16 sidebar-open:w-64 transition-all">
Expands when sidebar is open
</nav>Multi-rule custom variants:
@custom-variant theme-dark {
&:where([data-theme="dark"] *) {
@slot;
}
}
/* For group-like patterns */
@custom-variant pointer-fine (@media (pointer: fine));Note: Use @variant (without "custom") to apply existing variants within CSS blocks, and @custom-variant to define new variants.
Reference: Tailwind CSS Functions and Directives
Use @reference for CSS Module Integration
When using @apply in Vue/Svelte component styles or CSS modules, use @reference to import theme variables without duplicating CSS output.
Incorrect (duplicates styles):
<style scoped>
/* Imports entire stylesheet, duplicates in output */
@import "../styles/main.css";
.custom-button {
@apply bg-brand-500 px-4 py-2 rounded;
}
</style>Correct (@reference for zero duplication):
<style scoped>
/* References variables without emitting styles */
@reference "../styles/main.css";
.custom-button {
@apply bg-brand-500 px-4 py-2 rounded;
}
</style>In CSS modules:
/* button.module.css */
@reference "../../styles/main.css";
.button {
@apply bg-blue-500 text-white px-4 py-2 rounded;
}
.button:hover {
@apply bg-blue-600;
}Benefits:
- Access to theme variables and utilities
- Zero CSS duplication in output
- Works with scoped styles
- Proper cascade layer integration
Reference: Tailwind CSS Functions and Directives
Leverage Smart Utility Sorting
Tailwind CSS v4 automatically sorts utilities by property count, ensuring complex utilities appear earlier in the CSS. This means you can override custom utilities with simple utilities.
Incorrect (fighting specificity):
@utility button {
@apply bg-black text-white px-4 py-2 rounded;
}<!-- Expecting bg-indigo-500 to override, but unsure about specificity -->
<button class="button bg-indigo-500">
Click me
</button>Correct (trust smart sorting):
@utility button {
@apply bg-black text-white px-4 py-2 rounded;
}
/* button has 5 properties, sorted BEFORE single-property utilities */<!-- bg-indigo-500 (1 property) comes AFTER button (5 properties) -->
<button class="button bg-indigo-500">
<!-- Works: indigo background overrides black -->
Click me
</button>How sorting works: 1. Multi-property utilities sorted first (e.g., button) 2. Single-property utilities sorted after 3. Within same property count, alphabetical 4. Cascade layers handle component vs utility precedence
Reference: Tailwind CSS Reusing Styles
Understand Utility File Scope
Custom utilities defined with @utility are only available in the file where they're defined. For shared utilities, create a dedicated file and import it.
Incorrect (expecting global scope):
/* components/button.css */
@utility btn {
@apply px-4 py-2 rounded font-medium;
}/* components/card.css */
.card-action {
@apply btn; /* Error: btn not defined in this file */
}Correct (shared utilities file):
/* utilities.css */
@utility btn {
@apply px-4 py-2 rounded font-medium;
}
@utility card-shadow {
@apply shadow-md hover:shadow-lg transition-shadow;
}/* components/card.css */
@import "./utilities.css";
.card-action {
@apply btn; /* Works: imported from utilities.css */
}Organization pattern:
styles/
├── main.css # @import "tailwindcss" + @theme
├── utilities.css # Shared @utility definitions
└── components/
├── button.css # @import "../utilities.css"
└── card.css # @import "../utilities.css"Reference: Tailwind CSS Functions and Directives
Avoid Excessive Theme Variables
Every @theme variable becomes available as a utility class and adds to IDE autocomplete suggestions. Define only the tokens your design system actually needs to keep the developer experience clean and the CSS output focused.
Incorrect (excessive variables):
@theme {
/* 50 color shades when only 5 are used in the design */
--color-gray-50: oklch(0.985 0 0);
--color-gray-100: oklch(0.967 0 0);
--color-gray-150: oklch(0.945 0 0);
--color-gray-200: oklch(0.923 0 0);
/* ...40 more shades... */
--color-gray-950: oklch(0.145 0 0);
/* Clutters IDE autocomplete and adds unnecessary CSS variable declarations */
}Correct (minimal token set):
@theme {
/* Only define colors actually used in the design */
--color-gray-100: oklch(0.967 0 0);
--color-gray-300: oklch(0.869 0 0);
--color-gray-500: oklch(0.708 0 0);
--color-gray-700: oklch(0.373 0 0);
--color-gray-900: oklch(0.21 0 0);
}Use `@theme inline` to avoid CSS variable overhead:
@theme inline {
/* Values are inlined into utilities instead of generating CSS variables */
--font-sans: "Inter", sans-serif;
--color-brand: oklch(0.623 0.214 259.1);
}
/* Generates: .font-sans { font-family: "Inter", sans-serif; } */
/* Instead of: .font-sans { font-family: var(--font-sans); } */Benefits:
- Cleaner IDE autocomplete with only relevant tokens
- Fewer CSS variable declarations in output
- Clearer design system constraints
- Better maintainability
Note: Tailwind v4's JIT engine only generates utility classes for tokens actually used in your templates. The primary cost of excessive @theme variables is developer experience clutter, not bundle size.
Reference: Tailwind CSS Theme Variables
Use CSS-First Configuration Over JavaScript
Tailwind CSS v4 uses the @theme directive for configuration instead of JavaScript files. This provides a single source of truth and eliminates the need for context switching.
Incorrect (JavaScript configuration):
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
brand: {
100: "#e6f0ff",
500: "#0066ff",
900: "#003380",
},
},
fontFamily: {
display: ["Satoshi", "sans-serif"],
},
},
},
};Correct (CSS-first with @theme):
/* styles.css */
@import "tailwindcss";
@theme {
--color-brand-100: oklch(0.95 0.02 250);
--color-brand-500: oklch(0.55 0.21 260);
--color-brand-900: oklch(0.25 0.15 260);
--font-display: "Satoshi", "sans-serif";
}Benefits:
- All design tokens in one CSS file
- No JavaScript parsing overhead
- CSS variables available at runtime
- Better IDE autocomplete support
Reference: Tailwind CSS Theme Variables
Use Parentheses for CSS Variable References
Tailwind CSS v4 changes the syntax for referencing CSS variables in utility classes from square brackets to parentheses.
Incorrect (v3 square bracket syntax):
<div class="bg-[--brand-color]">
<!-- v3 syntax - may not work in v4 -->
</div>
<div class="text-[--heading-size]">
<!-- Square brackets for CSS variables -->
</div>Correct (v4 parentheses syntax):
<div class="bg-(--brand-color)">
<!-- v4 syntax for CSS variables -->
</div>
<div class="text-(--heading-size)">
<!-- Parentheses indicate variable reference -->
</div>Note: Square brackets are still used for arbitrary static values:
<div class="bg-[#ff5733]"><!-- Static arbitrary value --></div>
<div class="bg-(--custom-color)"><!-- CSS variable reference --></div>Reference: Tailwind CSS Upgrade Guide
Use Dynamic Utility Values
Tailwind CSS v4 supports dynamic values for many utilities without arbitrary value syntax. Grid columns, spacing, and other utilities accept any numeric value.
Incorrect (arbitrary value syntax):
<div class="grid grid-cols-[repeat(15,minmax(0,1fr))]">
<!-- Verbose arbitrary value syntax for non-standard column count -->
</div>
<div class="mt-[68px] w-[340px]">
<!-- Arbitrary pixel values -->
</div>Correct (dynamic utility values):
<div class="grid grid-cols-15">
<!-- Any column count works natively -->
</div>
<div class="mt-17 w-85">
<!-- Calculated from spacing scale: var(--spacing) * N -->
</div>How it works:
/* Generated CSS */
.mt-17 { margin-top: calc(var(--spacing) * 17); }
.w-85 { width: calc(var(--spacing) * 85); }
.grid-cols-15 { grid-template-columns: repeat(15, minmax(0, 1fr)); }Benefits:
- Cleaner class names
- Consistent spacing scale
- Better readability
- Fewer arbitrary values in markup
Reference: Tailwind CSS v4.0 Release
Use OKLCH Color Space for Vivid Colors
Tailwind CSS v4 defaults to OKLCH color space, providing wider P3 gamut colors and perceptually uniform lightness. Use OKLCH syntax for custom colors.
Incorrect (legacy sRGB hex values):
@theme {
--color-accent-500: #7c3aed;
--color-success-500: #22c55e;
--color-warning-500: #f59e0b;
}Correct (OKLCH with wider gamut):
@theme {
--color-accent-500: oklch(0.585 0.233 303.9);
--color-success-500: oklch(0.723 0.191 142.5);
--color-warning-500: oklch(0.769 0.188 70.08);
}Benefits:
- More vivid colors on P3 displays
- Perceptually uniform lightness across hues
- Better gradient interpolation
- Future-proof for HDR displays
Note: OKLCH colors gracefully fall back to sRGB on older displays.
Reference: Tailwind CSS v4.0 Release
Use @utility for Custom Utilities
Define custom utilities with @utility instead of @layer utilities. This enables automatic variant support and proper cascade layer sorting.
Incorrect (legacy @layer approach):
@layer utilities {
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
}
/* No automatic variant support */Correct (v4 @utility directive):
@utility scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}
/* Automatically works with hover:, focus:, md:, etc. */<div class="scrollbar-hide hover:scrollbar-default">
<!-- Variants work automatically -->
</div>Benefits:
- Automatic variant support (hover, focus, responsive)
- Proper cascade layer ordering
- Smart specificity sorting
- Consistent with built-in utilities
Reference: Tailwind CSS Functions and Directives
Use Container Queries for Component-Level Responsiveness
Use built-in container queries (@container, @sm:, @lg:) for components that should adapt to their container size, not viewport size.
Incorrect (viewport-based component):
<aside class="w-full lg:w-80">
<!-- Card adapts to viewport, not sidebar width -->
<div class="p-4 lg:p-6">
<h3 class="text-lg lg:text-xl">Title</h3>
<p class="text-sm lg:text-base">Description</p>
</div>
</aside>Correct (container-based component):
<aside class="w-full lg:w-80 @container">
<!-- Card adapts to sidebar width -->
<div class="p-4 @lg:p-6">
<h3 class="text-lg @lg:text-xl">Title</h3>
<p class="text-sm @lg:text-base">Description</p>
</div>
</aside>Container query variants:
<!-- Min-width queries (default) -->
<div class="@sm:flex @lg:grid">
<!-- Max-width queries -->
<div class="@max-md:hidden">
<!-- Range queries -->
<div class="@min-sm:@max-lg:flex">When to use container queries:
- Cards in variable-width layouts
- Sidebar components
- Reusable UI components
- Components in grid/flex containers
Reference: Tailwind CSS v4.0 Release
Define Custom Breakpoints in @theme
Add custom breakpoints using the @theme directive. This is useful for project-specific design requirements or adding intermediate breakpoints.
Incorrect (arbitrary values for breakpoints):
<div class="hidden min-[900px]:block min-[1400px]:flex">
<!-- Arbitrary values scattered across codebase -->
</div>Correct (custom theme breakpoints):
@import "tailwindcss";
@theme {
--breakpoint-xs: 480px;
--breakpoint-3xl: 1920px;
--breakpoint-4xl: 2560px;
}<div class="hidden xs:block 3xl:flex 4xl:grid">
<!-- Named breakpoints, consistent usage -->
</div>Override default breakpoints:
@theme {
/* Override existing breakpoints */
--breakpoint-sm: 600px; /* Was 640px */
--breakpoint-lg: 992px; /* Was 1024px */
}Benefits:
- Consistent breakpoint values across codebase
- Self-documenting (named vs arbitrary)
- Easy to update project-wide
- IDE autocomplete support
Reference: Tailwind CSS Theme Variables
Pair Hover with Active for Touch-Friendly Interactions
Tailwind CSS v4 only applies hover: styles on devices that support hover (@media (hover: hover)), preventing "sticky" hover states on touch devices. Always pair hover: with active: to provide feedback on both device types.
Incorrect (hover-only feedback):
<button class="bg-blue-500 hover:bg-blue-600">
<!-- Desktop: visual feedback on hover -->
<!-- Touch: no feedback at all — button appears unresponsive -->
</button>
<a href="/settings" class="text-gray-600 hover:text-blue-500">
<!-- Touch users get no indication the link is tappable -->
Settings
</a>Correct (hover + active for all devices):
<button class="bg-blue-500 hover:bg-blue-600 active:bg-blue-700">
<!-- Desktop: hover feedback + press feedback -->
<!-- Touch: press feedback via active: -->
</button>
<a href="/settings" class="text-gray-600 hover:text-blue-500 active:text-blue-600">
Settings
</a>Complete interactive pattern:
<button class="
bg-blue-500 text-white
hover:bg-blue-600
active:bg-blue-700
focus-visible:ring-2 focus-visible:ring-blue-400
disabled:opacity-50 disabled:pointer-events-none
">
Touch-friendly button
</button>Generated CSS in v4:
@media (hover: hover) {
.hover\:bg-blue-600:hover {
background-color: var(--color-blue-600);
}
}
/* active: applies on all devices — no media query wrapping */Reference: Tailwind CSS Upgrade Guide
Use Logical Properties for RTL Support
Use logical property utilities (ms-, me-, ps-, pe-) instead of physical properties (ml-, mr-, pl-, pr-) for automatic RTL layout support.
Incorrect (physical properties):
<div class="ml-4 mr-8 pl-2 pr-6">
<!-- Requires separate RTL styles -->
</div>
<div class="text-left">
<!-- Doesn't flip in RTL -->
</div>Correct (logical properties):
<div class="ms-4 me-8 ps-2 pe-6">
<!-- LTR: margin-left/right, padding-left/right -->
<!-- RTL: automatically flips to match direction -->
</div>
<div class="text-start">
<!-- LTR: text-align: left -->
<!-- RTL: text-align: right -->
</div>Logical property mapping:
| Physical | Logical | LTR | RTL |
|---|---|---|---|
ml-* | ms-* | left | right |
mr-* | me-* | right | left |
pl-* | ps-* | left | right |
pr-* | pe-* | right | left |
left-* | start-* | left | right |
right-* | end-* | right | left |
text-left | text-start | left | right |
text-right | text-end | right | left |
Reference: Tailwind CSS v4.0 Release
Use Mobile-First Responsive Design
Write base styles for mobile, then add complexity with breakpoint prefixes. This produces smaller CSS and follows progressive enhancement principles.
Incorrect (desktop-first, override down):
<div class="grid-cols-4 lg:grid-cols-4 md:grid-cols-2 sm:grid-cols-1">
<!-- Redundant: lg same as base -->
<!-- More CSS needed to override -->
</div>Correct (mobile-first, enhance up):
<div class="grid-cols-1 md:grid-cols-2 lg:grid-cols-4">
<!-- Base: 1 column (mobile) -->
<!-- md+: 2 columns (tablet) -->
<!-- lg+: 4 columns (desktop) -->
</div>Why mobile-first works better: 1. Base styles apply to all screen sizes 2. Breakpoints add complexity progressively 3. Smaller CSS output (fewer overrides) 4. Better performance on mobile devices
Breakpoint reference:
| Prefix | Min-width | Target |
|---|---|---|
| (none) | 0px | Mobile |
sm: | 640px | Large phones |
md: | 768px | Tablets |
lg: | 1024px | Laptops |
xl: | 1280px | Desktops |
2xl: | 1536px | Large screens |
Reference: Tailwind CSS Responsive Design
Set color-scheme for Native Dark Mode
Use the color-scheme utility to ensure native browser elements (scrollbars, form controls) match your theme.
Incorrect (mismatched native elements):
<html class="dark">
<body class="bg-gray-900 text-white">
<!-- Dark background, but scrollbars are still light -->
<div class="overflow-auto h-screen">
<!-- Light scrollbar on dark background -->
</div>
</body>
</html>Correct (coordinated color scheme):
<html class="dark scheme-dark">
<body class="bg-gray-900 text-white">
<!-- Scrollbars and native elements are dark -->
<div class="overflow-auto h-screen">
<!-- Dark scrollbar matches theme -->
</div>
</body>
</html>Dynamic color scheme:
<html class="scheme-light dark:scheme-dark">
<body class="bg-white dark:bg-gray-900">
<!-- Automatically switches native elements with theme -->
</body>
</html>Affected native elements:
- Scrollbars
- Form inputs (checkboxes, radios)
<select>dropdowns<input type="date">pickers- Auto-fill background colors
Reference: Tailwind CSS v4.0 Release
Use Class-Based Dark Mode for Control
By default, Tailwind v4 uses prefers-color-scheme. For user-controlled theme switching, configure class-based dark mode.
Incorrect (only system preference):
@import "tailwindcss";
/* Default: dark: responds only to OS setting */<!-- No way for users to manually toggle theme -->
<div class="bg-white dark:bg-gray-900">Correct (class-based control):
@import "tailwindcss";
@variant dark (&:where(.dark, .dark *));<!-- Toggle theme by adding/removing .dark class -->
<html class="dark">
<body class="bg-white dark:bg-gray-900">
<!-- Dark mode active -->
</body>
</html>Theme toggle implementation:
function toggleDarkMode() {
document.documentElement.classList.toggle("dark");
localStorage.setItem(
"theme",
document.documentElement.classList.contains("dark") ? "dark" : "light"
);
}
// On page load
if (localStorage.theme === "dark" ||
(!localStorage.theme && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
document.documentElement.classList.add("dark");
}Reference: Tailwind CSS Dark Mode
Use @theme inline and @theme static for Variable Control
Tailwind v4 provides @theme inline and @theme static modifiers to control how theme variables are emitted in the CSS output. Use inline to avoid CSS variable indirection, and static to force variable generation for shared libraries.
Incorrect (default @theme when runtime variables aren't needed):
@theme {
--font-sans: "Inter", sans-serif;
--color-brand: oklch(0.623 0.214 259.1);
}
/* Generates CSS variables on :root that may never be read at runtime */
/* .font-sans { font-family: var(--font-sans); } */
/* Nested variable resolution can produce unexpected results */Correct (@theme inline for direct value inlining):
@theme inline {
--font-sans: "Inter", sans-serif;
--color-brand: oklch(0.623 0.214 259.1);
}
/* No CSS variables on :root — values are inlined into utilities */
/* .font-sans { font-family: "Inter", sans-serif; } */
/* .text-brand { color: oklch(0.623 0.214 259.1); } */Use @theme static for shared libraries:
@theme static {
--color-primary: var(--color-brand-500);
--color-secondary: var(--color-blue-500);
}
/* Variables always emitted on :root, even if unused in this package */
/* Consumers in other packages can reference these variables */When to use each:
@theme(default) — most cases, balances runtime access with output size@theme inline— when you don't need runtime CSS variable access (e.g., fonts, static values)@theme static— when building shared libraries where consumers reference your variables
Reference: Tailwind CSS Theme Variables
Use Prefix for Variable Namespacing
When integrating Tailwind into existing projects or component libraries, use a prefix to prevent CSS variable conflicts.
Incorrect (potential conflicts):
@import "tailwindcss";
@theme {
--color-primary: oklch(0.623 0.214 259.1);
/* May conflict with existing --color-primary in project */
}Correct (prefixed variables):
@import "tailwindcss" prefix(tw);
@theme {
/* Define without prefix */
--color-primary: oklch(0.623 0.214 259.1);
--font-display: "Satoshi", sans-serif;
}/* Generated CSS variables are prefixed */
:root {
--tw-color-primary: oklch(0.623 0.214 259.1);
--tw-font-display: "Satoshi", sans-serif;
}<!-- Utility classes are also prefixed -->
<div class="tw:bg-primary tw:font-display">
Content
</div>When to use prefixes:
- Migrating existing projects with CSS variables
- Building embeddable widgets
- Creating component libraries
- Multi-framework applications
Reference: Tailwind CSS Upgrade Guide
Leverage Runtime CSS Variables
Tailwind CSS v4 exposes all theme values as CSS variables, enabling runtime customization without rebuilding CSS.
Incorrect (hardcoded theme values):
// Changing theme requires rebuild
const theme = {
primary: "#0066ff",
secondary: "#6b7280",
};
function applyTheme(theme) {
// Can't change Tailwind classes at runtime
}Correct (runtime CSS variable override):
@theme {
--color-primary: oklch(0.623 0.214 259.1);
--color-secondary: oklch(0.551 0.027 264.4);
}// Change theme at runtime without rebuild
function applyTheme(theme: { primary: string; secondary: string }) {
document.documentElement.style.setProperty("--color-primary", theme.primary);
document.documentElement.style.setProperty("--color-secondary", theme.secondary);
}
// Usage
applyTheme({
primary: "oklch(0.7 0.15 150)", // Green theme
secondary: "oklch(0.6 0.1 160)",
});Use cases:
- User-customizable themes
- White-label applications
- A/B testing color schemes
- Accessibility contrast modes
Reference: Tailwind CSS Theme Variables
Use Semantic Design Token Names
Name design tokens by their purpose, not their visual appearance. This enables theme switching and makes the design system more maintainable.
Incorrect (visual naming):
@theme {
--color-blue-500: oklch(0.623 0.214 259.1);
--color-gray-100: oklch(0.967 0 0);
--color-gray-900: oklch(0.21 0 0);
}<button class="bg-blue-500 text-gray-100">
<!-- What if brand color changes to green? -->
</button>Correct (semantic naming):
@theme {
/* Semantic tokens reference visual tokens */
--color-primary: oklch(0.623 0.214 259.1);
--color-surface: oklch(0.967 0 0);
--color-text: oklch(0.21 0 0);
/* Or map directly */
--color-button-bg: var(--color-primary);
--color-button-text: oklch(1 0 0);
}<button class="bg-primary text-button-text">
<!-- Purpose is clear, easy to change -->
</button>Token hierarchy:
@theme {
/* Primitive tokens */
--color-brand-500: oklch(0.623 0.214 259.1);
/* Semantic tokens */
--color-primary: var(--color-brand-500);
--color-interactive: var(--color-primary);
/* Component tokens (optional) */
--color-button-default: var(--color-interactive);
}Reference: Tailwind CSS Theme Variables
Use Explicit Border and Ring Colors
Tailwind CSS v4 changes default colors for borders and rings from gray-200/blue-500 to currentColor. Always specify colors explicitly.
Incorrect (relying on v3 defaults):
<div class="border px-4 py-3">
<!-- Border may be invisible (currentColor vs gray-200) -->
</div>
<input class="ring" />
<!-- Ring color unpredictable -->Correct (explicit colors):
<div class="border border-gray-200 px-4 py-3">
<!-- Explicit gray border -->
</div>
<input class="ring ring-blue-500" />
<!-- Explicit blue ring -->v4 default changes:
| Property | v3 Default | v4 Default |
|---|---|---|
| Border color | gray-200 | currentColor |
| Ring color | blue-500 | currentColor |
| Ring width | 3px | 1px |
| Placeholder | gray-400 | currentColor at 50% |
Reference: Tailwind CSS Upgrade Guide
Use via-none to Reset Gradient Stops
Tailwind CSS v4 preserves gradient values across variants instead of resetting them. Explicitly use via-none to remove a middle stop.
Incorrect (expecting gradient reset):
<div class="bg-linear-to-r from-red-500 via-orange-400 to-yellow-400
dark:from-blue-500 dark:to-teal-400">
<!-- v3: dark mode resets entire gradient -->
<!-- v4: dark mode keeps via-orange-400! -->
</div>Correct (explicit via-none):
<div class="bg-linear-to-r from-red-500 via-orange-400 to-yellow-400
dark:via-none dark:from-blue-500 dark:to-teal-400">
<!-- Explicitly remove via stop in dark mode -->
</div>How v4 works:
- Gradient stops are preserved across variants
- Each stop can be individually overridden
- Use
via-noneto convert 3-stop to 2-stop gradient - More consistent with other utility behaviors
Reference: Tailwind CSS Upgrade Guide
Use Trailing Important Modifier
Tailwind CSS v4 moves the important modifier (!) from the beginning to the end of utility classes for better readability.
Incorrect (v3 leading modifier):
<div class="!flex !bg-red-500 !p-4">
<!-- Leading exclamation marks -->
</div>Correct (v4 trailing modifier):
<div class="flex! bg-red-500! p-4!">
<!-- Trailing exclamation marks -->
</div>Benefits of trailing modifier:
- Reads left-to-right naturally
- Easier to spot important overrides
- Consistent with other modifier patterns
With variants:
<!-- v3 -->
<div class="hover:!bg-blue-500">
<!-- v4 -->
<div class="hover:bg-blue-500!">Reference: Tailwind CSS Upgrade Guide
Use Slash Opacity Modifier
Tailwind CSS v4 removes the deprecated opacity utilities (bg-opacity-*, text-opacity-*). Use the slash syntax for color opacity instead.
Incorrect (deprecated opacity utilities):
<div class="bg-blue-500 bg-opacity-50">
<!-- Deprecated in v4 -->
</div>
<p class="text-black text-opacity-75">
<!-- Two classes for one effect -->
</p>Correct (slash opacity modifier):
<div class="bg-blue-500/50">
<!-- Single class with opacity -->
</div>
<p class="text-black/75">
<!-- Cleaner, more readable -->
</p>With CSS variables:
<div class="bg-(--brand-color)/50">
<!-- Works with custom properties too -->
</div>Benefits:
- Single class instead of two
- Works with any color utility
- Compatible with CSS variables
- More readable markup
Reference: Tailwind CSS Upgrade Guide
Use Renamed Utility Classes
Tailwind CSS v4 renames several utility classes to create consistent scaling. Update these classes to prevent broken styles.
Incorrect (v3 class names):
<input class="shadow-sm blur-sm rounded-sm ring ring-blue-500" />
<button class="outline-none">Click me</button>Correct (v4 class names):
<input class="shadow-xs blur-xs rounded-xs ring-3 ring-blue-500" />
<button class="outline-hidden">Click me</button>Complete rename mapping:
| v3 Class | v4 Class | Reason |
|---|---|---|
shadow-sm | shadow-xs | Scale consistency |
shadow | shadow-sm | Scale consistency |
blur-sm | blur-xs | Scale consistency |
rounded-sm | rounded-xs | Scale consistency |
ring (3px) | ring-3 | Explicit width |
ring (1px) | ring | New default |
outline-none | outline-hidden | Semantic clarity |
Automated migration:
npx @tailwindcss/upgrade
# Automatically renames classes in your templatesReference: Tailwind CSS Upgrade Guide
Use Left-to-Right Variant Stacking
Tailwind CSS v4 changes variant stacking from right-to-left to left-to-right. Update stacked variants to maintain correct behavior.
Incorrect (v3 right-to-left order):
<ul class="*:py-2 first:*:pt-0 last:*:pb-0">
<!-- Child selector applied before first/last -->
</ul>
<div class="group-hover:dark:bg-black">
<!-- dark applied before group-hover -->
</div>Correct (v4 left-to-right order):
<ul class="*:py-2 *:first:pt-0 *:last:pb-0">
<!-- Child selector first, then first/last -->
</ul>
<div class="dark:group-hover:bg-black">
<!-- dark first, then group-hover -->
</div>Reading order:
- Read variants left-to-right
- Outer context first, inner context last
- Matches natural language order: "in dark mode, on group hover, make background black"
Reference: Tailwind CSS Upgrade Guide
Related skills
How it compares
Pick tailwind over generic CSS skills when the codebase already uses Tailwind CSS v4 and you need impact-ranked performance rules rather than general styling advice.
FAQ
What does the tailwind skill include?
The tailwind skill includes 44 Tailwind CSS v4 rules grouped into 8 categories, plus AGENTS.md as the full compiled guide and metadata.json for reference versioning in pproenca/dot-skills.
When should agents activate tailwind?
Agents should activate tailwind when writing, reviewing, or refactoring Tailwind CSS v4 code involving configuration, @theme, utility classes, responsive design, dark mode, container queries, or CSS output optimization.