Your First Utilities
Learn to read a Tailwind class name, then build one component from a plain box to a responsive, interactive, dark-mode-aware card.
Every Tailwind class follows the same shape. Once you can read one, you can guess most of the rest.
Anatomy of a class#
md:hover:bg-indigo-600/80
─┬ ──┬── ─┬ ───┬── ─┬─ ─┬
│ │ │ │ │ └─ opacity modifier → 80%
│ │ │ │ └────── shade → 600
│ │ │ └──────────── colour → indigo
│ │ └───────────────── property → background-color
│ └────────────────────── state variant → :hover
└────────────────────────── breakpoint → ≥ 48remRead it right to left: background colour indigo-600 at 80% opacity, on hover, from the medium breakpoint up.
| Part | Meaning | Docs |
|---|---|---|
bg-indigo-600 | The utility itself | Colors |
/80 | Opacity modifier | Colors |
hover: | State variant | States & Variants |
md: | Responsive variant | Responsive Design |
dark: | Colour scheme variant | Dark Mode |
[…] | Arbitrary value | Arbitrary Values |
Variants stack left to right and can be combined freely: dark:md:hover:bg-indigo-500.
The scales you will use constantly#
Almost every numeric utility draws on the same spacing scale, where 1 = 0.25rem (4px by default).
| Class | Value | Class | Value |
|---|---|---|---|
p-1 | 0.25rem | p-6 | 1.5rem |
p-2 | 0.5rem | p-8 | 2rem |
p-3 | 0.75rem | p-10 | 2.5rem |
p-4 | 1rem | p-12 | 3rem |
The same numbers work for m-*, gap-*, w-*, h-*, top-* and more. Learn it once.
Build a card, step by step#
1. Basic#
Start with structure and no styling decisions beyond spacing and colour.
<div class="max-w-sm rounded-xl border border-gray-200 bg-white p-6">
<h3 class="text-lg font-semibold text-gray-900">Zero Gravity Pen</h3>
<p class="mt-2 text-sm text-gray-600">
Writes in any orientation, including upside-down and in outer space.
</p>
<p class="mt-4 text-xl font-bold text-gray-900">$32.00</p>
</div>Every class maps to one declaration:
max-w-sm→max-width: 24remrounded-xl→border-radius: 0.75remborder border-gray-200→ a 1px border, explicitly colouredp-6→padding: 1.5remmt-2→margin-top: 0.5rem
2. Responsive#
Design mobile-first: unprefixed classes are the small-screen baseline, prefixed classes take over at larger widths.
<div class="max-w-md rounded-xl border border-gray-200 bg-white p-4 sm:p-6">
<h3 class="text-base font-semibold text-gray-900 sm:text-lg">Zero Gravity Pen</h3>
<p class="mt-2 text-sm text-gray-600">
Writes in any orientation, including upside-down and in outer space.
</p>
<div class="mt-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<p class="text-xl font-bold text-gray-900">$32.00</p>
<button class="rounded-lg bg-indigo-600 px-4 py-2 text-sm font-medium text-white">
Add to cart
</button>
</div>
</div>The footer stacks on phones (flex-col) and becomes a row from 40rem up (sm:flex-row).
3. Interactive#
Add state with variants rather than extra CSS.
<div class="max-w-md rounded-xl border border-gray-200 bg-white p-6 transition hover:border-indigo-300 hover:shadow-lg">
<h3 class="text-lg font-semibold text-gray-900">Zero Gravity Pen</h3>
<p class="mt-2 text-sm text-gray-600">
Writes in any orientation, including upside-down and in outer space.
</p>
<div class="mt-4 flex items-center justify-between">
<p class="text-xl font-bold text-gray-900">$32.00</p>
<button class="rounded-lg bg-indigo-600 px-4 py-2 text-sm font-medium text-white transition hover:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 active:bg-indigo-700">
Add to cart
</button>
</div>
</div>4. Advanced#
Dark mode and group-driven state, still without leaving the markup.
<a href="#" class="group block max-w-md rounded-xl border border-gray-200 bg-white p-6 transition hover:border-indigo-300 hover:shadow-lg dark:border-gray-700 dark:bg-gray-800 dark:hover:border-indigo-500">
<div class="flex items-start justify-between gap-4">
<h3 class="text-lg font-semibold text-gray-900 transition group-hover:text-indigo-600 dark:text-white dark:group-hover:text-indigo-400">
Zero Gravity Pen
</h3>
<span class="rounded-full bg-emerald-100 px-2 py-0.5 text-xs font-semibold text-emerald-800 dark:bg-emerald-900 dark:text-emerald-200">
In stock
</span>
</div>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-300">
Writes in any orientation, including upside-down and in outer space.
</p>
<p class="mt-4 text-xl font-bold text-gray-900 dark:text-white">$32.00</p>
</a>group on the parent lets children react to the parent's hover via group-hover:*. That is one of the highest-leverage variants in Tailwind — see States & Variants.
Utilities worth memorising first#
| Need | Reach for |
|---|---|
| Horizontal + vertical centring | flex items-center justify-center |
| Even spacing between children | flex gap-4 or grid gap-4 |
| Page container | mx-auto max-w-7xl px-6 |
| Card surface | rounded-xl border p-6 shadow-sm |
| Muted body text | text-sm text-gray-600 |
| Section heading | text-2xl font-semibold tracking-tight |
| Responsive column split | grid gap-6 md:grid-cols-2 |
Common mistakes#
- Using
sm:for phones.sm:means 40rem and up. Unprefixed classes are the mobile baseline. justify-centerto centre vertically.justify-*follows the main axis. In a row, vertical centring isitems-center.- Adding
flexand expecting a gap.gap-*needs a flex or grid container; on a block element it does nothing. - Guessing class names.
text-mediumandfont-lgdo not exist. It isfont-mediumandtext-lg.
Related topics#
- Utility-First CSS — the philosophy and its limits
- Flexbox — the layout mode you will use most
- Responsive Design — breakpoints in depth
- Cheat Sheet — everything on one page