tailwind css
Utility-first CSS framework with Vite
$ npx docs2skills add tailwind-vite-setupTailwind CSS
Utility-first CSS framework for rapid UI development
What this skill does
Tailwind CSS is a utility-first CSS framework that provides low-level utility classes to build custom designs directly in your markup. Instead of writing custom CSS, you compose designs using pre-built utility classes like flex, pt-4, text-center, and rotate-90.
It works by scanning all your HTML files, JavaScript components, and templates for class names, then generates only the CSS you actually use. This approach results in smaller CSS bundles and faster development cycles while maintaining complete design flexibility.
The framework excels at responsive design, state variants (hover, focus, etc.), and maintaining design consistency across large projects without the complexity of traditional CSS methodologies.
Prerequisites
- Node.js 14.13.1 or higher
- A build tool (Vite, PostCSS, or Webpack)
- Basic HTML/CSS knowledge
- Project using a supported framework (React, Vue, Svelte, etc.)
Quick start
# Install with Vite (recommended)
npm install tailwindcss @tailwindcss/vite
# Add to vite.config.js
import tailwindcss from '@tailwindcss/vite'
export default {
plugins: [tailwindcss()]
}
# Import in CSS file
@import "tailwindcss";
# Use in HTML
<h1 class="text-3xl font-bold underline">Hello world!</h1>
Core concepts
Utility-first: Build interfaces using small, single-purpose utility classes rather than writing custom CSS.
Responsive design: All utilities can be applied conditionally at different breakpoints using prefixes like sm:, md:, lg:, xl:, 2xl:.
State variants: Apply utilities on hover, focus, and other states using prefixes like hover:, focus:, active:.
Design tokens: Consistent spacing, colors, and sizing through a default design system that can be customized.
Purging/JIT: Only generates CSS for classes actually used in your markup, keeping file sizes minimal.
Key utility classes
Layout & Positioning:
flex,grid,block,inline,hiddenrelative,absolute,fixed,stickytop-4,right-0,bottom-2,left-8z-10,z-50,z-auto
Flexbox & Grid:
justify-center,justify-between,items-center,items-startgrid-cols-3,col-span-2,gap-4,gap-x-2,gap-y-8flex-wrap,flex-nowrap,flex-1,flex-shrink-0
Spacing:
p-4(padding),px-8(horizontal),pt-2(top)m-6(margin),mx-auto(center),-mt-4(negative)space-x-4,space-y-2(between children)
Typography:
text-sm,text-lg,text-3xl,text-6xlfont-thin,font-bold,font-blacktext-left,text-center,text-righttext-gray-600,text-blue-500,text-red-800
Colors & Backgrounds:
bg-blue-500,bg-gray-100,bg-transparenttext-white,text-gray-900,text-red-500border-gray-300,border-blue-600
Common patterns
Responsive card component:
<div class="max-w-sm mx-auto bg-white rounded-xl shadow-lg overflow-hidden md:max-w-2xl">
<div class="md:flex">
<div class="md:shrink-0">
<img class="h-48 w-full object-cover md:h-full md:w-48" src="image.jpg">
</div>
<div class="p-8">
<h3 class="text-lg font-semibold text-gray-900">Card Title</h3>
<p class="mt-2 text-gray-600">Description text here.</p>
</div>
</div>
</div>
Button variants:
<!-- Primary button -->
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Primary
</button>
<!-- Outline button -->
<button class="bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded">
Outline
</button>
Responsive navigation:
<nav class="flex items-center justify-between flex-wrap bg-blue-500 p-6">
<div class="flex items-center flex-shrink-0 text-white mr-6">
<span class="font-semibold text-xl">Brand</span>
</div>
<div class="block lg:hidden">
<button class="flex items-center px-3 py-2 border rounded text-white border-white hover:text-white hover:border-white">
<svg class="fill-current h-3 w-3" viewBox="0 0 20 20">
<path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/>
</svg>
</button>
</div>
<div class="w-full block flex-grow lg:flex lg:items-center lg:w-auto">
<div class="text-sm lg:flex-grow">
<a href="#" class="block mt-4 lg:inline-block lg:mt-0 text-white hover:text-white mr-4">
Link
</a>
</div>
</div>
</nav>
Dark mode:
<div class="bg-white dark:bg-gray-800">
<h1 class="text-gray-900 dark:text-white">
This adapts to dark mode
</h1>
<p class="text-gray-600 dark:text-gray-300">
Secondary text
</p>
</div>
Configuration
vite.config.js (Vite setup):
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})
tailwind.config.js (customization):
export default {
content: ['./src/**/*.{html,js,jsx,ts,tsx,vue}'],
theme: {
extend: {
colors: {
'custom-blue': '#1e40af',
},
spacing: {
'72': '18rem',
'84': '21rem',
},
fontFamily: {
'sans': ['Inter', 'system-ui'],
}
}
},
plugins: [],
}
Dark mode configuration:
export default {
darkMode: 'class', // or 'media'
// ... rest of config
}
Best practices
- Use consistent spacing scale: Stick to the default spacing scale (4px increments) for visual consistency
- Leverage component extraction: Extract repeated utility combinations into components rather than duplicating classes
- Mobile-first responsive design: Start with mobile styles, then add responsive prefixes for larger screens
- Use semantic color names: Prefer
bg-primary-500overbg-blue-500in your custom theme - Combine with CSS-in-JS sparingly: Use
@applydirective or custom CSS only when utilities aren't sufficient - Optimize for readability: Break long class lists across multiple lines in templates
- Purge unused styles: Ensure your build process removes unused utilities in production
- Use design tokens: Define consistent colors, spacing, and typography in your config
Gotchas and common mistakes
Class name detection: Tailwind only generates CSS for complete class names found in your files. 'text-' + color won't work - use safelist or write out full class names.
Specificity issues: Tailwind utilities have low specificity. Custom CSS may override utilities unexpectedly. Use !important utilities like !text-red-500 when needed.
Purging configuration: Incorrect content paths in config can cause styles to be purged unexpectedly. Include all files that contain Tailwind classes.
Responsive breakpoints: Mobile styles apply to all screen sizes unless overridden. sm:text-lg means "text-lg from small screens and up", not "text-lg only on small screens".
Arbitrary values: Use square brackets for one-off values: top-[117px], text-[#1da1f2]. Don't overuse - consider adding to theme instead.
Plugin order: Some plugins must be loaded in specific order. Always check plugin documentation for requirements.
CSS imports: Must import Tailwind after any custom CSS to ensure proper cascading: custom CSS first, then @import "tailwindcss".
File extensions: Include all relevant file extensions in your content configuration. Missing .vue, .svelte, or .tsx files will cause missing styles.
Dynamic class names: Safelist dynamic classes or ensure the complete class name appears somewhere in your source code for Tailwind to detect it.