One of the more common complaints about Tailwind CSS is that it clutters markup. What the critics usually miss is the flip side: Tailwind eliminates entire blocks of CSS by encoding multi-property patterns into a single class. Once you know which classes pull double (or triple) duty, you stop reaching for a custom stylesheet for the small stuff.
This is a practical reference. For each class below, the CSS it generates is shown exactly. All examples use Tailwind CSS v4, which ships as a CSS-first framework — no tailwind.config.js required for most projects. Install it via npm install tailwindcss @tailwindcss/vite and add @import "tailwindcss" to your CSS entry point.
Text truncation
truncate
Single-line ellipsis in traditional CSS requires three declarations that are easy to forget individually:
/* Old CSS */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
Tailwind's truncate class emits all three:
<p class="truncate">Very long product description that should not wrap...</p>
line-clamp-{n}
Multi-line truncation used to require a small essay of webkit properties. Before @tailwindcss/line-clamp was absorbed into the core (Tailwind 3.3, and still built in on v4), developers wrote this:
/* Old CSS */
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
Now it is one class:
<p class="line-clamp-3">Blog excerpt that cuts off after three lines...</p>
Arbitrary values work the same way: line-clamp-[5].
Positioning shortcuts
inset-0
Overlays, modals, and absolutely-positioned fill elements need all four edges zeroed. The traditional approach:
/* Old CSS */
top: 0;
right: 0;
bottom: 0;
left: 0;
Tailwind compresses that to:
<div class="absolute inset-0 bg-black/50"></div>
There are also axis variants: inset-x-0 sets left and right; inset-y-0 sets top and bottom. Useful for sticky sidebars and full-height panels.
inset-x-auto / inset-y-auto
Horizontal centering of absolutely-positioned elements used to look like this:
/* Old CSS */
left: 50%;
right: 50%;
transform: translateX(-50%);
With Tailwind you still need the transform, but combining left-1/2 -translate-x-1/2 is shorter and scannable. For the common pattern of a centered overlay bar:
<div class="absolute left-1/2 -translate-x-1/2 bottom-4 rounded-full px-4 py-2 bg-white shadow">
Toolbar
</div>
Sizing
size-{n}
Added in Tailwind v3.4 and fully available in v4. It sets width and height simultaneously:
/* Old CSS */
width: 3rem; /* 48px / size-12 */
height: 3rem;
<img class="size-12 rounded-full" src="avatar.jpg" alt="User" />
Works with all the standard spacing scale values, fractions (size-1/2), and arbitrary values (size-[72px]). No more writing w-12 h-12 everywhere.
size-full
Stretch an element to fill its parent:
/* Old CSS */
width: 100%;
height: 100%;
<canvas class="size-full"></canvas>
Accessibility
sr-only
Visually hidden but readable by screen readers. The raw CSS behind this class is genuinely awkward to memorize:
/* Old CSS */
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
The Tailwind one-liner:
<span class="sr-only">Open navigation menu</span>
not-sr-only reverses it — useful when you want an element visible only on focus (skip-to-content links):
<a href="#main" class="sr-only focus:not-sr-only focus:fixed focus:top-4 focus:left-4">
Skip to content
</a>
Flex and grid shortcuts
flex items-center justify-center
Three classes, but they replace five CSS declarations that developers write from muscle memory every day:
/* Old CSS */
display: flex;
align-items: center;
justify-content: center;
<div class="flex items-center justify-center h-screen">
<p>Perfectly centered</p>
</div>
mx-auto
Horizontal centering of a block element:
/* Old CSS */
margin-left: auto;
margin-right: auto;
<div class="max-w-2xl mx-auto px-6">Content</div>
space-x-{n} / space-y-{n}
Adding uniform spacing between sibling elements used to mean either gaps (flex only) or lobotomized owl selectors. Tailwind's space utilities apply margin to every child except the first using the * + * pattern:
/* Old CSS — the "lobotomized owl" */
> * + * {
margin-left: 1rem;
}
<nav class="flex space-x-4">
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>
Note: if you are already in a flex or grid context, prefer gap-4 — it handles both axes cleanly and does not rely on margin direction.
Visual effects
divide-x / divide-y
Drawing dividers between list items or table rows without adding extra markup:
/* Old CSS */
> * + * {
border-top-width: 1px;
border-color: #e5e7eb;
}
<ul class="divide-y divide-gray-200">
<li class="py-3">Item one</li>
<li class="py-3">Item two</li>
<li class="py-3">Item three</li>
</ul>
ring-{n}
Focus rings and card outlines typically required box-shadow math:
/* Old CSS */
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5);
<button class="focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
Save
</button>
Tailwind v4 also adds inset-ring-{n} which renders the ring inside the border box — useful for cards that need an inner highlight without affecting layout.
aspect-video / aspect-square
Before the CSS aspect-ratio property was widely supported, maintaining a 16/9 ratio meant the padding-top hack:
/* Old CSS — the padding hack */
position: relative;
padding-top: 56.25%; /* 9/16 */
<div class="aspect-video w-full overflow-hidden rounded-xl">
<iframe class="size-full" src="..."></iframe>
</div>
aspect-square gives you aspect-ratio: 1 / 1. Arbitrary values work: aspect-[4/3].
New in Tailwind v4
field-sizing-content
Auto-resizing textareas without JavaScript:
/* Old CSS */
/* Not possible in pure CSS before field-sizing */
<textarea class="field-sizing-content w-full min-h-20 resize-none border rounded p-3"></textarea>
The textarea grows with its content. field-sizing: content is now a real CSS property (shipped in Chrome 123, Safari 18) and Tailwind v4 surfaces it directly.
bg-linear-{angle}
Angled gradients used to require writing the degree value inline:
/* Old CSS */
background-image: linear-gradient(45deg, #3b82f6, #8b5cf6);
<div class="bg-linear-45 from-blue-500 to-violet-500"></div>
Tailwind v4 adds bg-conic-* and bg-radial-* on the same pattern. The color interpolation modifier is also new: bg-linear-to-r/oklch runs the gradient through the OKLCH color space for perceptually uniform transitions.
Starting animations with starting:
The CSS @starting-style at-rule lets browsers animate elements from their initial render state (useful for dialogs and toasts entering the DOM). Before Tailwind v4, this required a custom @keyframes block or a JavaScript workaround:
<dialog class="open:opacity-100 opacity-0 starting:open:opacity-0 transition-opacity">
Content
</dialog>
The starting: variant generates the @starting-style wrapper so the dialog fades in on open with zero JavaScript.
Combining them: a real-world card
Here is a service card component that uses several of these one-liners together. Notice how much custom CSS it avoids:
<article class="flex flex-col gap-4 rounded-2xl bg-white p-6 ring-1 ring-gray-200 shadow-sm hover:shadow-md transition-shadow">
<div class="flex items-center gap-3">
<div class="size-10 rounded-lg bg-blue-50 flex items-center justify-center shrink-0">
<svg class="size-5 text-blue-600" ...></svg>
</div>
<h3 class="font-semibold text-gray-900 truncate">Drain Cleaning</h3>
</div>
<p class="text-sm text-gray-600 line-clamp-3">
Full drain cleaning and jetting service for residential and commercial properties.
Includes camera inspection on request.
</p>
<a href="/services/drain-cleaning" class="mt-auto text-sm font-medium text-blue-600 hover:text-blue-700">
Learn more →
</a>
</article>
That single component handles layout (flex flex-col gap-4), sizing (size-10, size-5), truncation (truncate, line-clamp-3), focus/hover states, and transitions — without a line of custom CSS.
Quick reference
truncate— overflow hidden + ellipsis + nowrap (3 props)line-clamp-{n}— multi-line text truncation (4 props)inset-0— top/right/bottom/left all zero (4 props)inset-x-0/inset-y-0— two-edge shortcutssize-{n}— width + height together (2 props)size-full— 100% width + 100% heightsr-only— visually hidden but screen-reader accessible (8 props)not-sr-only— reverses sr-onlymx-auto— margin-left + margin-right auto (2 props)space-x-{n}/space-y-{n}— inter-sibling spacing via margindivide-x/divide-y— borders between sibling elementsring-{n}— box-shadow focus ring without shadow mathinset-ring-{n}— inner border via inset shadow (new in v4)aspect-video/aspect-square— aspect-ratio without the padding hackfield-sizing-content— auto-resizing textarea (new in v4)bg-linear-{angle}/bg-conic-*/bg-radial-*— gradient shorthands (v4)starting:—@starting-styleentry animations (v4)
The pattern across all of these is the same: Tailwind knows what you mean by "visually hidden" or "fill this container" better than a raw property can, so it names the intent rather than the implementation. That is what utility-first actually means in practice — not that you avoid CSS, but that you stop writing the same boilerplate declarations over and over across a dozen files.