Tailwind Concepts
How the utility class system works — responsive prefixes, state variants, and the config file
Why First — The Scenario
You're a CA with a 50-page Excel workbook. Every sheet needs the same formatting: company blue headers, bold totals row, gray alternating rows, specific font size. You do it manually on Sheet 1. Then repeat for all 50 sheets. An hour later you realise the blue color was wrong. You repeat everything.
Now imagine a global style definition at the top of the workbook: "headers are this exact blue, totals are this exact format." Change it once, every sheet updates.
This is what Tailwind's design system does. Every color, every spacing value, every font size is defined once in tailwind.config.ts. The classes you write in your components reference those definitions. Change the definition, every component that uses it updates.
The Core Idea: One Class, One Property
Traditional CSS mixes multiple properties in one rule:
Tailwind breaks this apart. Each CSS property gets its own class name:
bg-white→background-color: whitep-4→padding: 16px(1 unit = 4px, so 4 units = 16px)rounded-lg→border-radius: 8pxshadow-sm→box-shadow: 0 1px 3px rgba(0,0,0,0.1)
The result is identical. But with Tailwind, everything is visible right where the element is defined. No hunting through CSS files.
CSS Property to Tailwind Class — Reference Table
This table is your translation dictionary. Keep it open while building your first few projects:
| What you want | CSS property | Tailwind class |
|---|---|---|
| Bold text | font-weight: 700 | font-bold |
| Semi-bold text | font-weight: 600 | font-semibold |
| Red text | color: red | text-red-500 |
| Gray text | color: #6b7280 | text-gray-500 |
| Blue background | background-color: blue | bg-blue-500 |
| White background | background-color: white | bg-white |
| Display as flex | display: flex | flex |
| Display as grid | display: grid | grid |
| Hidden | display: none | hidden |
| Padding all sides 16px | padding: 16px | p-4 |
| Padding top+bottom 8px | padding-top: 8px; padding-bottom: 8px | py-2 |
| Padding left+right 16px | padding-left: 16px; padding-right: 16px | px-4 |
| Margin top 24px | margin-top: 24px | mt-6 |
| Full width | width: 100% | w-full |
| Full viewport height | height: 100vh | h-screen |
| Font size 18px | font-size: 18px | text-lg |
| Font size 24px | font-size: 24px | text-2xl |
| Rounded corners | border-radius: 8px | rounded-lg |
| Border | border: 1px solid | border |
| Box shadow | box-shadow: (subtle) | shadow-md |
| Center text | text-align: center | text-center |
| Uppercase text | text-transform: uppercase | uppercase |
| Pointer cursor | cursor: pointer | cursor-pointer |
| Overflow hidden | overflow: hidden | overflow-hidden |
The spacing scale: Tailwind uses a 4px base unit. p-1 = 4px, p-2 = 8px, p-4 = 16px, p-6 = 24px, p-8 = 32px. Once you know the scale, every spacing class makes immediate sense.
Responsive Prefixes
This is one of Tailwind's most powerful features — and it is much simpler than it sounds.
The Scenario
Your app needs to show 3 cards in a row on a laptop, 2 cards on a tablet, and 1 card (full width) on a mobile phone. In traditional CSS, you'd write three separate blocks with @media queries. In Tailwind, you add prefixes to the same class.
Breakpoints
| Prefix | Minimum screen width | Targets |
|---|---|---|
| (none) | All screens | Mobile first — applies everywhere |
sm: | 640px+ | Larger phones and small tablets |
md: | 768px+ | Tablets |
lg: | 1024px+ | Laptops and desktops |
xl: | 1280px+ | Large desktops |
How They Work
Tailwind is mobile-first. A class without a prefix applies to all screen sizes. A prefix means "apply this from this size upward."
Reading it left to right:
grid-cols-1→ always 1 column (mobile)md:grid-cols-2→ 2 columns from 768px uplg:grid-cols-3→ 3 columns from 1024px up
State Variants
State variants let you apply a class only when an element is in a specific state — hovered, focused, checked, disabled.
Hover
Focus
Disabled
Combining Variants
Variants can be stacked. hover:md:text-lg means "on medium screens and up, when hovered, use large text." You will rarely need this, but it is possible.
Dark Mode
Tailwind has built-in dark mode support. The dark: prefix applies a class only when the user's system is in dark mode (or when your app switches to dark mode).
Dark mode works out of the box with the shadcn/ui setup. The theme toggle button from shadcn/ui handles switching. You just need to add dark: variants to your custom elements.
The tailwind.config.ts File
Every Tailwind project has a configuration file at the root. This is where the design system is defined.
You will rarely need to edit this file during training. It is already set up correctly. Understanding what it does helps you read errors and understand where design tokens come from.
The content array is critical. Tailwind only generates CSS for classes it actually sees in your files. If a class is not listed in a content path, Tailwind won't include it in the final CSS bundle. This is why the build output is tiny — only the classes you use are compiled.
How Tailwind Knows What Classes to Generate
This often confuses beginners: Tailwind doesn't generate CSS for all possible classes — that would be thousands of lines. It scans your files, finds every class name you've written, and generates CSS only for those classes.
This means:
The second example breaks because Tailwind scans your source code as text. It sees bg-${color}-500 and cannot determine that this means bg-blue-500. The class never gets generated. The styling silently fails.
When you need dynamic styling based on a variable, use a lookup object:
Now Tailwind sees the full class names in your source and generates them correctly.
Summary
The four concepts that cover 90% of what you'll use:
- Utility classes — one class, one CSS property. Read left to right on the element.
- Responsive prefixes —
sm:,md:,lg:make your layout adapt to screen size. - State variants —
hover:,focus:,disabled:apply styles conditionally. - Dark mode —
dark:applies styles in dark mode.
The next page covers the specific classes you will reach for every day.