Tailwind CSS Basics: Style with Utility Classes
States and Responsive Design
In this lesson you will
- Style hover, focus and other states with variants
- Build responsive layouts mobile first with breakpoint prefixes
- Combine variants and understand how they compile
Introduction
A design must respond to the user: a button changes on hover, a menu rearranges on a phone. In Tailwind this is done with variants: a prefix before a class, separated by a colon. hover:bg-blue-700 means "apply bg-blue-700 only on hover".
State variants
HTML
<button class="rounded-lg bg-blue-600 px-4 py-2 text-white hover:bg-blue-700 focus:outline-2 focus:outline-offset-2 focus:outline-blue-600 active:bg-blue-800 disabled:opacity-50">
Save
</button>Common state variants:
| Variant | When it applies |
|---|---|
hover: | pointer over the element |
focus: / focus-visible: | element has focus / keyboard focus |
active: | being pressed |
disabled: | disabled form control |
first: / last: / odd: / even: | position among siblings |
placeholder: | placeholder text |
checked: | checked checkbox or radio |
Use focus-visible: for focus rings so mouse clicks do not show them while keyboard users still do.
What hover really does
I compiled hover:bg-blue-600 and found that v4 wraps hover rules in @media (hover: hover). That means hover styles apply only on devices whose main input can hover, so touch screens do not get sticky hover states after a tap.
Responsive design is mobile first
Breakpoint variants such as md: apply at that width and above. Unprefixed classes apply to all sizes, starting from the smallest. So you design for phones first, then add changes for larger screens.
| Prefix | Minimum width |
|---|---|
sm: | 40rem (640px) |
md: | 48rem (768px) |
lg: | 64rem (1024px) |
xl: | 80rem (1280px) |
2xl: | 96rem (1536px) |
These values match the rules I saw when compiling, for example md:flex became @media (width >= 48rem).
HTML
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
<div>Card</div>
<div>Card</div>
<div>Card</div>
</div>This reads: one column by default, two columns from sm, three from lg. A common mistake is thinking sm: means "on small screens". It means "from the small breakpoint up". Use unprefixed classes for the smallest size.
Quick quiz
What does md:flex mean in Tailwind?
Targeting a range
To apply a style only below a breakpoint, use max-md: (compiled to width < 48rem). To limit to one range, combine them: md:max-lg:hidden.
A responsive navbar
HTML
<header class="flex flex-col gap-4 p-4 md:flex-row md:items-center md:justify-between">
<a href="/" class="text-xl font-bold">Brand</a>
<nav class="flex flex-col gap-2 md:flex-row md:gap-6">
<a href="/docs">Docs</a>
<a href="/pricing">Pricing</a>
</nav>
</header>On phones it stacks in a column. From md upward it becomes one row with space between.
Dark mode
The dark: variant applies dark-mode styles. By default it follows the user's operating system setting through prefers-color-scheme:
HTML
<div class="bg-white text-gray-900 dark:bg-gray-900 dark:text-white">
Adapts to the system theme
</div>A later lesson shows how to switch dark mode with a button.
Other useful variants
motion-reduce:respects the user's reduced-motion setting, for examplemotion-reduce:transition-none.print:for print styles.group-hover:andpeer-*for styling based on another element (covered in the intermediate course).
Stacking variants
Variants combine from left to right: md:hover:bg-blue-700 applies the background at md and wider and on hover. dark:md:hover:bg-blue-500 adds the dark condition as well. I compiled these and each produced nested media conditions with the hover rule inside.
Transitions
Add smoothness with transition and a duration:
HTML
<button class="bg-blue-600 transition duration-200 hover:bg-blue-700">
Smooth
</button>Respect reduced motion with motion-reduce:transition-none for larger animations.
Try it yourself
Build a pricing section with three cards. Make it one column on phones, three columns from lg. Add hover:shadow-lg transition to each card, a dark-mode background, and test by resizing the window.
Summary
- Variants are prefixes like
hover:,focus-visible:anddisabled:that apply a utility only in that state. - Breakpoint prefixes (
sm40rem,md48rem,lg64rem,xl80rem,2xl96rem) are mobile first and mean "this width and up". - Variants stack left to right, and
dark:follows the system theme by default.
Lesson complete
+20 XP
Nice work. Keep going while it is fresh.
Sources and further reading