Skip to content

Tailwind CSS Guide

Tailwind CSS is a utility-first CSS framework. Instead of writing custom CSS, you compose styles from small, single-purpose classes directly in your markup. This guide explains the core concepts with interactive demos you can play with.

Traditional CSS requires naming things and writing rules in a separate file:

.card {
padding: 1rem;
border-radius: 0.5rem;
background-color: #3b82f6;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

With Tailwind, you express the same thing inline:

<div class="p-4 rounded-lg bg-blue-500 shadow-md">...</div>

Every class maps to exactly one CSS property. p-4 is padding: 1rem. rounded-lg is border-radius: 0.5rem. No naming, no context switching, no dead CSS.

Here is that exact card, built with Tailwind classes right inside this MDX file:

🚀

This is a Tailwind card written directly in MDX using utility classes. No custom CSS file needed — just bg-gradient-to-r, rounded-xl, shadow-lg, and friends.

Tailwind makes flexbox intuitive. The class names mirror the CSS properties:

Tailwind ClassCSS Property
flexdisplay: flex
flex-rowflex-direction: row
flex-colflex-direction: column
justify-centerjustify-content: center
items-centeralign-items: center
gap-4gap: 1rem

CSS Grid in Tailwind is just as composable. The key classes are:

Tailwind ClassCSS Property
griddisplay: grid
grid-cols-3grid-template-columns: repeat(3, 1fr)
col-span-2grid-column: span 2
gap-4gap: 1rem

Tailwind uses mobile-first breakpoint prefixes. Unprefixed classes apply at all sizes. Prefixed classes apply at that breakpoint and above.

PrefixMin WidthCommon Use
(none)0pxMobile default
sm:640pxLarge phones, small tablets
md:768pxTablets
lg:1024pxLaptops
xl:1280pxDesktops

A responsive grid looks like this:

<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4"></div>

This means: 1 column on mobile, 2 on small screens, 4 on large screens. No media queries to write.

MDX supports raw HTML directly, so you can apply Tailwind classes with plain <div> tags:

Blue Card

Green Card

Purple Card

Heads up — This is a custom callout built entirely with Tailwind utilities: border-l-4, border-amber-400, bg-amber-50, and dark:bg-amber-950 for dark mode support.

🔥

Gradients, shadows, and rounded corners — all composed from single-purpose classes. This card uses bg-gradient-to-br, from-pink-500, via-red-500, to-orange-500, shadow-xl, and rounded-xl.

The MDX source for the colored cards above is just:

<div class="grid grid-cols-1 sm:grid-cols-3 gap-4">
<div class="rounded-lg bg-blue-500 p-4 text-white text-center font-bold shadow-md">Blue Card</div>
...
</div>

Tailwind uses a consistent spacing scale based on 0.25rem (4px) increments:

ClassValuePixels
p-000px
p-10.25rem4px
p-20.5rem8px
p-41rem16px
p-61.5rem24px
p-82rem32px

This scale applies to padding (p-), margin (m-), gap (gap-), width (w-), height (h-), and more. The consistency means your spacing always looks intentional.

Tailwind ships with a curated color palette. Each color has shades from 50 (lightest) to 950 (darkest):

<div class="bg-blue-500 text-white">Default blue</div>
<div class="bg-blue-100 text-blue-900">Light blue surface</div>
<div class="border border-blue-300">Blue border</div>

The pattern is always {property}-{color}-{shade}:

  • bg- for background
  • text- for text color
  • border- for border color
  • ring- for focus rings

You can also use opacity modifiers: bg-blue-500/50 gives blue at 50% opacity.

Tailwind handles hover, focus, and other states with prefixes — just like responsive breakpoints:

<button
class="bg-blue-500 hover:bg-blue-600 active:bg-blue-700
focus:ring-2 focus:ring-blue-300
disabled:opacity-50 disabled:cursor-not-allowed"
>
Click me
</button>

Common state prefixes:

hover:

Mouse over the element. The most common interactive state.

focus:

Element has keyboard or click focus. Essential for accessibility.

active:

Element is being pressed/clicked. Brief visual feedback.

disabled:

Element is disabled. Typically reduces opacity and changes cursor.

No naming

You never waste time inventing class names like .card-wrapper-inner-header. The utilities describe what they do.

No dead CSS

Unused classes are automatically removed at build time. Your CSS only contains what you actually use.

Local reasoning

You can understand an element’s styles by reading its classes. No jumping between files or tracing specificity.

Safe changes

Changing a class only affects that element. No cascading side effects, no “I changed this and broke something else.”