Tailwind Fundamentals
Utility-first CSS fundamentals with Tailwind including class composition, spacing, typography, and layout primitives
You are an expert in utility-first CSS development with Tailwind CSS. ## Key Points - **Compose in markup first.** Reach for `@apply` or component extraction only when duplication is genuinely painful. - **Use the design system.** Stick to the default scale (`p-4`, `text-lg`, `rounded-md`) for consistency; reach for arbitrary values sparingly. - **Leverage semantic HTML.** Tailwind styles appearance, not semantics. Keep using proper elements (`<nav>`, `<main>`, `<button>`). - **Sort classes consistently.** Use the official Prettier plugin (`prettier-plugin-tailwindcss`) to auto-sort class order. - **Prefix responsive and state variants logically.** Read classes left-to-right as "base, then sm, then md" or "default, then hover." - **Overusing `@apply`.** This recreates the problems Tailwind eliminates. Prefer framework-level component abstraction. - **Forgetting `min-h-screen` on layout wrappers.** Without it, short pages leave empty space below content. - **Using `w-screen` instead of `w-full`.** `w-screen` (100vw) includes scrollbar width and causes horizontal overflow; `w-full` (100%) respects the parent container. - **Conflicting utilities.** Applying both `flex` and `grid` on the same element or contradictory widths leads to unpredictable results. Only one layout mode per element. - **Not purging unused styles in production.** Ensure your `content` paths in the Tailwind config cover all template files so the final CSS is small. ## Quick Example ```html <div class="bg-blue-100 text-blue-900">Light blue background, dark blue text</div> <div class="bg-slate-800 text-slate-100">Dark slate background, light text</div> <button class="bg-indigo-600 text-white hover:bg-indigo-700">Action</button> ``` ```html <div class="top-[117px] grid grid-cols-[1fr_2fr_1fr] bg-[#1a1a2e]"> Custom values </div> ```
skilldb get tailwind-skills/Tailwind FundamentalsFull skill: 200 linesUtility-First Fundamentals — Tailwind CSS
You are an expert in utility-first CSS development with Tailwind CSS.
Overview
Tailwind CSS is a utility-first framework where you style elements by composing small, single-purpose classes directly in markup. Instead of writing custom CSS, you apply pre-built utilities like flex, pt-4, text-center, and bg-blue-500 to build designs entirely in HTML.
Core Philosophy
Tailwind's utility-first approach is a deliberate inversion of traditional CSS architecture. Instead of writing semantic class names that describe what an element is and maintaining a separate stylesheet that describes how it looks, you apply small, composable utility classes that describe appearance directly in the markup. This eliminates the indirection layer between HTML and CSS, removes the need to invent naming conventions, and makes it immediately visible what any element looks like just by reading its class list.
The power of this approach is not that it replaces CSS knowledge — it is that it codifies CSS knowledge into a constrained design system. When you use p-4 instead of writing padding: 1rem, you are not saving keystrokes; you are committing to a spacing scale that keeps your entire application consistent. The constraint is the feature. Arbitrary values exist as an escape hatch, but reaching for them frequently is a signal that your configuration needs updating, not that the constraint should be bypassed.
Tailwind works best when combined with component-based frameworks. The common objection that utility classes create duplication is solved by extracting reusable components in React, Vue, or Svelte — not by creating CSS abstractions with @apply. The component is the abstraction boundary, and within that boundary, utility classes provide maximum clarity and zero indirection.
Core Concepts
The Utility-First Workflow
Traditional CSS creates an abstraction layer between HTML and styles. Tailwind inverts this: styles live in the markup, eliminating the need to invent class names or maintain separate stylesheets.
<!-- Traditional approach -->
<div class="card-wrapper">
<h2 class="card-title">Hello</h2>
</div>
<!-- Tailwind utility-first approach -->
<div class="rounded-lg border border-gray-200 bg-white p-6 shadow-sm">
<h2 class="text-xl font-semibold text-gray-900">Hello</h2>
</div>
Spacing Scale
Tailwind uses a consistent spacing scale based on 0.25rem increments:
| Class | Value |
|---|---|
p-0 | 0 |
p-1 | 0.25rem (4px) |
p-2 | 0.5rem (8px) |
p-4 | 1rem (16px) |
p-8 | 2rem (32px) |
Spacing applies to padding (p-), margin (m-), gap (gap-), width (w-), height (h-), and more. Directional variants exist: px- (horizontal), py- (vertical), pt- (top), mr- (right), etc.
Typography
<!-- Font size and weight -->
<p class="text-sm font-medium">Small medium text</p>
<h1 class="text-4xl font-bold tracking-tight">Large heading</h1>
<!-- Text color and alignment -->
<p class="text-center text-gray-600">Centered muted text</p>
<!-- Line height and letter spacing -->
<p class="text-lg leading-relaxed tracking-wide">Readable body text</p>
Color System
Tailwind provides a palette with shades from 50 (lightest) to 950 (darkest):
<div class="bg-blue-100 text-blue-900">Light blue background, dark blue text</div>
<div class="bg-slate-800 text-slate-100">Dark slate background, light text</div>
<button class="bg-indigo-600 text-white hover:bg-indigo-700">Action</button>
Layout with Flexbox and Grid
<!-- Flexbox row with gap -->
<div class="flex items-center gap-4">
<img class="h-10 w-10 rounded-full" src="avatar.jpg" alt="" />
<div>
<p class="font-medium">Jane Doe</p>
<p class="text-sm text-gray-500">Developer</p>
</div>
</div>
<!-- CSS Grid -->
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
<div class="rounded-lg bg-white p-4 shadow">Card 1</div>
<div class="rounded-lg bg-white p-4 shadow">Card 2</div>
<div class="rounded-lg bg-white p-4 shadow">Card 3</div>
</div>
<!-- Centering -->
<div class="flex min-h-screen items-center justify-center">
<p>Perfectly centered</p>
</div>
Borders, Shadows, and Rounded Corners
<div class="rounded-md border border-gray-300 shadow-sm">Subtle card</div>
<div class="rounded-2xl border-2 border-blue-500 shadow-lg">Prominent card</div>
<div class="divide-y divide-gray-200">
<div class="py-3">Row 1</div>
<div class="py-3">Row 2</div>
</div>
Sizing and Constraints
<!-- Fixed and relative sizing -->
<div class="h-64 w-full">Full width, fixed height</div>
<div class="min-h-screen">At least viewport height</div>
<div class="max-w-prose mx-auto">Readable width container</div>
<!-- Aspect ratio -->
<div class="aspect-video w-full">16:9 container</div>
Implementation Patterns
Extracting Repeated Utilities with @apply
When a combination is repeated many times, extract it to a CSS class:
/* input.css */
@layer components {
.btn-primary {
@apply rounded-md bg-indigo-600 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600;
}
}
Prefer component abstractions in your framework (React components, Vue components) over @apply for most cases.
State Variants
<!-- Hover, focus, active -->
<button class="bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 active:bg-blue-800">
Click me
</button>
<!-- Group hover -->
<a class="group flex items-center gap-2">
<span class="text-gray-700 group-hover:text-blue-600">Link text</span>
<svg class="h-4 w-4 text-gray-400 group-hover:text-blue-600">...</svg>
</a>
<!-- First, last, odd, even -->
<ul>
<li class="first:pt-0 last:pb-0 border-b py-3 odd:bg-gray-50">Item</li>
</ul>
Arbitrary Values
When the design system does not cover a value, use square bracket notation:
<div class="top-[117px] grid grid-cols-[1fr_2fr_1fr] bg-[#1a1a2e]">
Custom values
</div>
Best Practices
- Compose in markup first. Reach for
@applyor component extraction only when duplication is genuinely painful. - Use the design system. Stick to the default scale (
p-4,text-lg,rounded-md) for consistency; reach for arbitrary values sparingly. - Leverage semantic HTML. Tailwind styles appearance, not semantics. Keep using proper elements (
<nav>,<main>,<button>). - Sort classes consistently. Use the official Prettier plugin (
prettier-plugin-tailwindcss) to auto-sort class order. - Prefix responsive and state variants logically. Read classes left-to-right as "base, then sm, then md" or "default, then hover."
Common Pitfalls
- Overusing
@apply. This recreates the problems Tailwind eliminates. Prefer framework-level component abstraction. - Forgetting
min-h-screenon layout wrappers. Without it, short pages leave empty space below content. - Using
w-screeninstead ofw-full.w-screen(100vw) includes scrollbar width and causes horizontal overflow;w-full(100%) respects the parent container. - Conflicting utilities. Applying both
flexandgridon the same element or contradictory widths leads to unpredictable results. Only one layout mode per element. - Not purging unused styles in production. Ensure your
contentpaths in the Tailwind config cover all template files so the final CSS is small.
Anti-Patterns
-
@applyeverywhere. Extracting utilities into CSS classes with@applyrecreates the abstraction layer Tailwind eliminates. If you find yourself writing.card { @apply rounded-lg border p-6 shadow-sm; }, extract a framework component instead. -
Fighting the design system with arbitrary values. Littering markup with
w-[347px],mt-[13px], andtext-[#4a5568]defeats the purpose of a constrained utility system. If a value is used more than once, add it to the Tailwind config; if it is truly one-off, question whether the design is correct. -
Treating Tailwind as inline styles. Tailwind utilities are not inline styles — they participate in the cascade, support responsive prefixes, state variants, and dark mode. Developers who avoid Tailwind because "it looks like inline styles" miss that utilities provide a design-system-constrained vocabulary that inline styles never offer.
-
Mixing layout modes on a single element. Applying both
flexandgridto the same element, or combining conflicting width utilities likew-fullandw-64, produces unpredictable results. Each element gets one layout mode and one sizing strategy. -
Skipping the Prettier plugin. Without
prettier-plugin-tailwindcss, class lists accumulate in random order, making them harder to scan and more likely to contain duplicates or conflicts. Consistent class ordering is not cosmetic — it is a readability and maintenance tool.
Install this skill directly: skilldb add tailwind-skills
Related Skills
Tailwind Animations
Animation utilities, transitions, custom keyframes, and motion patterns with Tailwind CSS
Tailwind Component Patterns
Common UI component patterns including cards, navbars, forms, modals, and badges built with Tailwind CSS
Tailwind Custom Config
Customizing tailwind.config.js to extend themes, add custom colors, fonts, spacing, and configure content paths
Tailwind Dark Mode
Dark mode strategies including class-based toggling, media queries, and CSS variable theming with Tailwind CSS
Tailwind Plugins
Writing custom Tailwind CSS plugins to add utilities, components, base styles, and variants
Tailwind Responsive Design
Responsive breakpoints, mobile-first design patterns, and adaptive layouts with Tailwind CSS