Tailwind CSS 36 🎨 Responsive Design Breakpoints and Mobile-First Workflow
Every Tailwind utility you have written so far applies at every screen size. A flex class makes an element a flex container on a phone, a tablet, and a widescreen monitor. A text-lg class sets the font size to 1.125rem regardless of how much horizontal space is available. This is fine for simple layouts, but it breaks down the moment a design needs to change across screen sizes. A three-column grid that works on a desktop is unusable on a phone. A horizontal navigation bar that fits on a laptop overflows on a small screen. Responsive design is not optional — it is the difference between a layout that adapts and a layout that shatters.
Tailwind’s responsive system is built on a single, consistent idea: breakpoint prefixes. A utility prefixed with md: applies only at the md breakpoint and above. A utility without a prefix applies at all sizes. The prefixes compose with the same utilities you already know — there are no separate responsive classes to learn, only prefixed versions of the classes you already use. This means the entire utility API is available at every breakpoint, and the only new concept is the prefix itself.
The system is mobile-first, which is the opposite of how many CSS frameworks work. In Tailwind, an unprefixed utility applies to the smallest screen and every larger screen. A prefixed utility applies only at that breakpoint and larger. There is no way to say “only on mobile” with a single class — you write the mobile styles unprefixed, and then override them at larger breakpoints. This inverts the mental model: instead of designing for desktop and adding mobile overrides, you design for mobile and add desktop enhancements.
This chapter covers three areas. First, why breakpoint prefixes and mobile-first exist — what problem the mobile-first cascade solves and why it produces simpler, more maintainable responsive code. Second, how to use the default breakpoints — the sm, md, lg, xl, and 2xl prefixes, how they cascade, and how to apply them to any utility. Third, how to structure responsive layouts — the patterns for stacking on mobile and spreading on desktop, responsive grids, responsive typography, and responsive visibility. The chapter ends with a complete example session, a quick reference, best practices, common pitfalls, real-world examples, and diagrams showing the mobile-first cascade and how breakpoint prefixes compose.
Key point: Tailwind is mobile-first — an unprefixed utility applies at every screen size, and a prefixed utility like md: applies at that breakpoint and larger. You write the mobile layout first, then layer on larger-screen overrides. There is no “mobile-only” prefix; mobile is the default .
Why breakpoint prefixes and mobile-first exist
The proliferation problem. Before utility-first CSS, responsive design meant writing media queries by hand. A single component might have three or four @media blocks, each with a handful of property overrides. The CSS grew quadratically: every component needed its own breakpoints, every breakpoint needed its own rules, and the relationship between them was implicit in the source order. A change to the base style required checking every media query that overrode it. Tailwind’s breakpoint prefixes replace the manual media queries with a consistent naming scheme. The breakpoint is part of the class name, so the responsive behavior is visible in the markup, not hidden in a separate stylesheet .
The desktop-first problem. The traditional approach to responsive CSS is desktop-first: write the desktop layout as the base style, then add max-width media queries to override for smaller screens. This works, but it produces a specific kind of complexity. Each override must undo the desktop style, and the undoing is often more verbose than the original. A three-column grid becomes a one-column grid by overriding grid-template-columns, gap, and sometimes the display itself. The overrides accumulate, and the cascade becomes a series of corrections. Mobile-first inverts this: the base style is the mobile layout, which is usually the simplest, and larger screens add complexity rather than removing it. A one-column grid becomes a three-column grid by changing one property. The additions are incremental, and the cascade builds up instead of tearing down .
The default-is-mobile principle. Mobile-first means the unprefixed utility is the mobile style. This is not just a convention — it is a statement about which screen size is the baseline. The smallest screen gets the simplest layout, and every larger screen is an enhancement. This matches how most designs should work: a phone shows the essential content in a single column, and a desktop has the space to show more. Starting from mobile forces you to prioritize, because you cannot fit everything on a small screen. Starting from desktop encourages adding until the layout breaks, then patching with media queries .
The single-utility-multiple-breakpoints principle. Every Tailwind utility can be prefixed with any breakpoint. text-sm can become md:text-base and lg:text-lg. flex can become md:grid. hidden can become lg:block. This means there is no separate “responsive API” — the responsive system is a naming convention layered on top of the existing utilities. You learn one set of utilities and one prefix syntax, and the combination covers every responsive case .
The cascade-order problem. Tailwind’s breakpoints cascade in a fixed order: sm, md, lg, xl, 2xl. A utility at md: applies at md and every larger breakpoint, unless overridden by a larger breakpoint. This means the order of the prefixes in the class list does not matter — md:flex lg:grid and lg:grid md:flex produce the same result, because the cascade is determined by the breakpoint order, not the source order. This is different from hand-written media queries, where source order determines which rule wins. Tailwind’s fixed order makes the cascade predictable and eliminates a whole class of specificity bugs .
The trade-off. Mobile-first requires thinking about the smallest screen first, which can feel backwards if you are used to designing on a large monitor. It also means that “mobile-only” styles require a different approach: you write the mobile style unprefixed and override it at sm: or md:, rather than writing a max-width query. And the fixed breakpoint set — sm, md, lg, xl, 2xl — may not match every design’s needs, requiring customization. The trade-off is between the simplicity of a consistent, mobile-first system and the flexibility of arbitrary media queries.
a. The default breakpoints
Tailwind ships with five breakpoints by default. Each is a min-width media query, meaning the styles apply at that width and above .
| Prefix | Min-width | Typical target |
|---|---|---|
sm: | 40rem (640px) | Large phones, small tablets |
md: | 48rem (768px) | Tablets |
lg: | 64rem (1024px) | Laptops |
xl: | 80rem (1280px) | Desktops |
2xl: | 96rem (1536px) | Large desktops |
The breakpoints are min-width queries, so md: means “at 768px and wider.” There is no max-width breakpoint in the default set. To target only mobile, you write the mobile style unprefixed and override it at sm: or md: .
A utility with a breakpoint prefix applies at that breakpoint and every larger one, unless a larger breakpoint overrides it. This is the cascade:
<div class="text-sm md:text-base lg:text-lg">
Responsive text
</div>
- At all sizes:
text-smapplies (unprefixed). - At
md(768px) and above:md:text-baseoverridestext-sm. - At
lg(1024px) and above:lg:text-lgoverridesmd:text-base.
The result: small text on mobile, medium text on tablet, large text on desktop. The unprefixed class is the base; the prefixed classes are the overrides at each breakpoint .
The breakpoints apply to every utility. There is no utility that cannot be prefixed. flex, grid, hidden, block, p-4, m-2, text-center, bg-blue-500 — all of them accept a breakpoint prefix:
<div class="flex flex-col md:flex-row lg:justify-between">
<div class="p-4 md:p-6 lg:p-8">Content</div>
</div>
On mobile: a column flex container with p-4 padding. On md: a row flex container with p-6 padding. On lg: a row flex container with p-8 padding and space-between justification .
b. The mobile-first cascade
The mobile-first cascade has a specific shape. Unprefixed utilities apply everywhere. Prefixed utilities apply at their breakpoint and larger. A larger breakpoint overrides a smaller one, and a smaller breakpoint overrides the unprefixed base .
This means the class list is read from smallest to largest, with each breakpoint adding or overriding. The unprefixed classes are the foundation; each prefixed group is a layer on top:
<div class="
grid grid-cols-1
sm:grid-cols-2
lg:grid-cols-3
xl:grid-cols-4
">
...
</div>
- All sizes: one column (
grid-cols-1). - At
sm(640px) and above: two columns (sm:grid-cols-2). - At
lg(1024px) and above: three columns (lg:grid-cols-3). - At
xl(1280px) and above: four columns (xl:grid-cols-4).
The grid starts as a single column and gains columns as the screen grows. The mobile layout is the simplest, and each breakpoint adds capacity .
The cascade also means that a prefixed utility does not need to be repeated at every larger breakpoint. md:flex applies at md, lg, xl, and 2xl unless a larger breakpoint overrides it. If you want flex at md and above, one md:flex is enough .
To create a “mobile-only” style, you write the style unprefixed and override it at sm: or md:. For example, to hide an element on mobile and show it on desktop, you write hidden lg:block:
<div class="hidden lg:block">
Visible only on large screens
</div>
hidden applies at all sizes. lg:block overrides it at lg and above. The element is hidden on mobile and tablets, visible on laptops and desktops. There is no max-lg:hidden needed because the mobile-first cascade handles it with the unprefixed base .
c. Structuring responsive layouts
Three patterns cover most responsive layouts: stacking and spreading, responsive grids, and responsive visibility.
Stacking and spreading. The most common responsive pattern is a layout that stacks vertically on mobile and spreads horizontally on larger screens. This is done with flex-col on mobile and md:flex-row on desktop:
<div class="flex flex-col md:flex-row gap-4">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
On mobile, the items stack in a column. On md and above, they sit in a row. The gap-4 applies at all sizes .
Responsive grids. Grid layouts change column counts at different breakpoints:
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
<div>Card 1</div>
<div>Card 2</div>
<div>Card 3</div>
</div>
One column on mobile, two on small tablets, three on laptops. The gap-6 applies at all sizes. The grid is defined once, and the column count changes at each breakpoint .
Responsive visibility. Elements can be shown or hidden at different breakpoints:
<nav class="hidden md:flex gap-4">
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
<button class="md:hidden">Menu</button>
The full navigation is hidden on mobile and shown on md and above. The menu button is shown on mobile and hidden on md and above. This is the standard pattern for responsive navigation: a hamburger menu on mobile, a full nav bar on desktop .
Complete Example Session
<!-- ============================================
PART 1: THE MOBILE LAYOUT (UNPREFIXED)
============================================ -->
<!-- Everything here applies at all screen sizes.
This is the baseline — the simplest layout. -->
<div class="p-4">
<h1 class="text-2xl font-bold">Dashboard</h1>
<div class="mt-4 space-y-4">
<div class="bg-white p-4 rounded shadow">Card 1</div>
<div class="bg-white p-4 rounded shadow">Card 2</div>
<div class="bg-white p-4 rounded shadow">Card 3</div>
</div>
</div>
<!-- ============================================
PART 2: ADDING A BREAKPOINT FOR TABLETS
============================================ -->
<!-- At md and above, the padding increases and
the cards arrange in a two-column grid. -->
<div class="p-4 md:p-6">
<h1 class="text-2xl md:text-3xl font-bold">Dashboard</h1>
<div class="mt-4 grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="bg-white p-4 rounded shadow">Card 1</div>
<div class="bg-white p-4 rounded shadow">Card 2</div>
<div class="bg-white p-4 rounded shadow">Card 3</div>
</div>
</div>
<!-- ============================================
PART 3: ADDING A BREAKPOINT FOR DESKTOPS
============================================ -->
<!-- At lg and above, the padding increases again
and the cards arrange in a three-column grid. -->
<div class="p-4 md:p-6 lg:p-8">
<h1 class="text-2xl md:text-3xl lg:text-4xl font-bold">Dashboard</h1>
<div class="mt-4 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 lg:gap-6">
<div class="bg-white p-4 rounded shadow">Card 1</div>
<div class="bg-white p-4 rounded shadow">Card 2</div>
<div class="bg-white p-4 rounded shadow">Card 3</div>
</div>
</div>
<!-- ============================================
PART 4: RESPONSIVE NAVIGATION
============================================ -->
<!-- The full nav is hidden on mobile and shown
at md. The menu button is shown on mobile
and hidden at md. -->
<nav class="flex items-center justify-between p-4">
<div class="text-xl font-bold">Logo</div>
<!-- Full navigation: hidden on mobile, flex at md -->
<div class="hidden md:flex gap-6">
<a href="/" class="hover:text-blue-500">Home</a>
<a href="/about" class="hover:text-blue-500">About</a>
<a href="/contact" class="hover:text-blue-500">Contact</a>
</div>
<!-- Menu button: flex on mobile, hidden at md -->
<button class="flex md:hidden">Menu</button>
</nav>
<!-- ============================================
PART 5: STACKING TO SPREADING
============================================ -->
<!-- A hero section that stacks on mobile and
spreads into two columns at lg. -->
<section class="flex flex-col lg:flex-row items-center gap-8 p-6 lg:p-12">
<div class="flex-1">
<h2 class="text-3xl lg:text-5xl font-bold">Build faster</h2>
<p class="mt-4 text-gray-600">Ship your ideas in record time.</p>
</div>
<div class="flex-1">
<img src="/hero.png" alt="Hero" class="w-full rounded-lg" />
</div>
</section>
<!-- ============================================
PART 6: RESPONSIVE TYPOGRAPHY
============================================ -->
<!-- Font sizes increase at each breakpoint.
The base is mobile; larger screens get
larger type. -->
<article class="max-w-prose mx-auto p-4">
<h1 class="text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-bold">
Article Title
</h1>
<p class="mt-4 text-base sm:text-lg leading-relaxed">
Article body text that grows with the screen.
</p>
</article>
<!-- ============================================
PART 7: RESPONSIVE SPACING
============================================ -->
<!-- Padding and margin increase at larger
breakpoints. The base spacing is tight;
larger screens get more breathing room. -->
<div class="px-4 sm:px-6 md:px-8 lg:px-12">
<div class="py-8 md:py-12 lg:py-16">
<div class="space-y-4 md:space-y-6 lg:space-y-8">
<p>Content 1</p>
<p>Content 2</p>
</div>
</div>
</div>
<!-- ============================================
PART 8: RESPONSIVE VISIBILITY
============================================ -->
<!-- Different content for different screens.
Mobile-only, tablet-only, and desktop-only
elements. -->
<div>
<!-- Mobile only -->
<p class="block md:hidden">Viewing on mobile</p>
<!-- Tablet and up -->
<p class="hidden md:block lg:hidden">Viewing on tablet</p>
<!-- Desktop only -->
<p class="hidden lg:block">Viewing on desktop</p>
</div>
<!-- ============================================
PART 9: RESPONSIVE SIDEBAR LAYOUT
============================================ -->
<!-- A dashboard layout: sidebar stacked on mobile,
side-by-side at lg. -->
<div class="flex flex-col lg:flex-row min-h-screen">
<!-- Sidebar: full width on mobile, fixed width at lg -->
<aside class="w-full lg:w-64 bg-gray-100 p-4">
<nav class="flex flex-row lg:flex-col gap-4">
<a href="/">Dashboard</a>
<a href="/settings">Settings</a>
<a href="/profile">Profile</a>
</nav>
</aside>
<!-- Main content: fills remaining space at lg -->
<main class="flex-1 p-4 lg:p-8">
<h1 class="text-2xl lg:text-3xl font-bold">Welcome back</h1>
</main>
</div>
<!-- ============================================
PART 10: THE FULL RESPONSIVE PAGE
============================================ -->
<!-- All patterns combined: responsive nav,
responsive grid, responsive typography,
responsive spacing, responsive sidebar. -->
<div class="min-h-screen bg-gray-50">
<nav class="flex items-center justify-between p-4 md:p-6">
<div class="text-xl font-bold">Logo</div>
<div class="hidden md:flex gap-6">
<a href="/">Home</a>
<a href="/about">About</a>
</div>
<button class="flex md:hidden">Menu</button>
</nav>
<div class="flex flex-col lg:flex-row">
<aside class="w-full lg:w-64 bg-white p-4 lg:p-6">
<nav class="flex flex-row lg:flex-col gap-4">
<a href="/">Dashboard</a>
<a href="/settings">Settings</a>
</nav>
</aside>
<main class="flex-1 p-4 md:p-6 lg:p-8">
<h1 class="text-2xl md:text-3xl lg:text-4xl font-bold">
Dashboard
</h1>
<div class="mt-6 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 lg:gap-6">
<div class="bg-white p-4 rounded shadow">Card 1</div>
<div class="bg-white p-4 rounded shadow">Card 2</div>
<div class="bg-white p-4 rounded shadow">Card 3</div>
</div>
</main>
</div>
</div>
The ten parts show the mobile-first cascade from the simplest case to the full page: unprefixed mobile styles, then md: overrides, then lg: overrides, applied to navigation, layout, grid, typography, spacing, and visibility.
Quick Reference
Default Breakpoints
| Prefix | Min-width | Typical target |
|---|---|---|
| (none) | 0 | Mobile |
sm: | 640px | Large phones |
md: | 768px | Tablets |
lg: | 1024px | Laptops |
xl: | 1280px | Desktops |
2xl: | 1536px | Large desktops |
The Cascade
| Class | Applies at |
|---|---|
text-sm | All sizes |
md:text-base | md and above |
lg:text-lg | lg and above |
Common Responsive Patterns
| Pattern | Mobile | Desktop |
|---|---|---|
| Stack to spread | flex-col | md:flex-row |
| Single to multi-column | grid-cols-1 | md:grid-cols-2 lg:grid-cols-3 |
| Hide on mobile | hidden | md:block |
| Show only on mobile | block | md:hidden |
| Responsive padding | p-4 | md:p-6 lg:p-8 |
| Responsive text | text-sm | md:text-base lg:text-lg |
Prefix Order
| Order | Result |
|---|---|
md:flex lg:grid | Same as lg:grid md:flex |
| Cascade determined by breakpoint order, not class order | Fixed: sm → md → lg → xl → 2xl |
Best Practices
✅ Do This:
<!-- Start with mobile, add breakpoints for larger -->
<div class="text-sm md:text-base lg:text-lg"> <!-- ✅ -->
<!-- Use one breakpoint for a range, not every breakpoint -->
<div class="hidden md:block"> <!-- ✅ -->
<!-- Stack on mobile, spread on desktop -->
<div class="flex flex-col md:flex-row"> <!-- ✅ -->
<!-- Change grid columns at breakpoints -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3"> <!-- ✅ -->
<!-- Increase spacing at larger screens -->
<div class="p-4 md:p-6 lg:p-8"> <!-- ✅ -->
<!-- Show mobile-only content with unprefixed + hide at breakpoint -->
<p class="block md:hidden">Mobile only</p> <!-- ✅ -->
❌ Don’t Do This:
<!-- Don't write desktop-first and override down -->
<div class="text-lg sm:text-sm"> <!-- ❌ -->
<!-- Don't repeat the same utility at every breakpoint -->
<div class="flex md:flex lg:flex"> <!-- ❌ -->
<!-- Don't use max-width prefixes — Tailwind is mobile-first -->
<div class="max-md:hidden"> <!-- ❌ -->
<!-- Don't forget the unprefixed base -->
<div class="md:flex-row"> <!-- ❌ -->
<!-- Don't assume class order matters -->
<div class="lg:grid md:flex"> <!-- ❌ -->
<!-- Don't use arbitrary breakpoints when defaults work -->
<div class="min-[800px]:flex"> <!-- ❌ -->
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Desktop styles on mobile | Forgetting the unprefixed class | Write mobile first, then override |
| Responsive styles not applying | Missing min-width meta tag | Add <meta name="viewport" content="width=device-width, initial-scale=1"> |
| Cascade not working as expected | Assuming class order matters | Breakpoint order is fixed: sm → md → lg |
| Mobile-only style needs a prefix | Thinking in desktop-first terms | Write unprefixed, override at sm: or md: |
| Breakpoints too granular | Adding a prefix at every size | Use the smallest number of breakpoints that works |
| Custom breakpoints needed | Defaults don’t match design | Customize in the Tailwind config |
| Responsive images not resizing | Fixed width set | Use w-full or max-w-full |
| Text too small on mobile | Base font size not set | Use text-base or larger as the mobile base |
Real-World Examples
1. Responsive Navigation
<nav class="flex items-center justify-between p-4">
<div class="font-bold">Logo</div>
<div class="hidden md:flex gap-4">...</div>
<button class="md:hidden">Menu</button>
</nav>
2. Responsive Card Grid
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
3. Stack to Spread
<div class="flex flex-col md:flex-row gap-6">
4. Responsive Padding
<div class="p-4 md:p-8 lg:p-12">
5. Responsive Typography
<h1 class="text-2xl md:text-4xl lg:text-6xl font-bold">
6. Sidebar Layout
<div class="flex flex-col lg:flex-row">
<aside class="w-full lg:w-64">...</aside>
<main class="flex-1">...</main>
</div>
7. Mobile-Only Element
<p class="block md:hidden">Mobile only</p>
8. Desktop-Only Element
<p class="hidden lg:block">Desktop only</p>
9. Responsive Hero
<section class="flex flex-col lg:flex-row items-center gap-8 p-6 lg:p-12">
10. Responsive Gap
<div class="flex gap-2 md:gap-4 lg:gap-6">
Visual
The Mobile-First Cascade
┌──────────────────────────────────────────────────────────────┐
│ MOBILE-FIRST CASCADE │
│ │
│ Class: text-sm md:text-base lg:text-lg │
│ │
│ Mobile (0px) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ text-sm │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ md (768px) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ text-sm ← overridden by md:text-base │ │
│ │ text-base │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ lg (1024px) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ text-sm ← overridden by md:text-base │ │
│ │ text-base ← overridden by lg:text-lg │ │
│ │ text-lg │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ Unprefixed applies everywhere. Prefixed overrides at │
│ that breakpoint and above. Larger breakpoints win. │
│ │
└──────────────────────────────────────────────────────────────┘
Stack to Spread
┌──────────────────────────────────────────────────────────────┐
│ STACK TO SPREAD │
│ │
│ class="flex flex-col md:flex-row gap-4" │
│ │
│ Mobile (flex-col): │
│ ┌──────────────┐ │
│ │ Item 1 │ │
│ ├──────────────┤ │
│ │ Item 2 │ │
│ ├──────────────┤ │
│ │ Item 3 │ │
│ └──────────────┘ │
│ │
│ md and above (flex-row): │
│ ┌──────────┬──────────┬──────────┐ │
│ │ Item 1 │ Item 2 │ Item 3 │ │
│ └──────────┴──────────┴──────────┘ │
│ │
│ The flex direction changes at md. The gap applies │
│ at all sizes. │
│ │
└──────────────────────────────────────────────────────────────┘
Responsive Grid Columns
┌──────────────────────────────────────────────────────────────┐
│ RESPONSIVE GRID │
│ │
│ class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3" │
│ │
│ Mobile (grid-cols-1): │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Card 1 │ │
│ ├──────────────────────────────────────────────────────┤ │
│ │ Card 2 │ │
│ ├──────────────────────────────────────────────────────┤ │
│ │ Card 3 │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ sm (grid-cols-2): │
│ ┌──────────────────────┬──────────────────────┐ │
│ │ Card 1 │ Card 2 │ │
│ ├──────────────────────┼──────────────────────┤ │
│ │ Card 3 │ │ │
│ └──────────────────────┴──────────────────────┘ │
│ │
│ lg (grid-cols-3): │
│ ┌──────────┬──────────┬──────────┐ │
│ │ Card 1 │ Card 2 │ Card 3 │ │
│ └──────────┴──────────┴──────────┘ │
│ │
│ One class, three layouts. The grid is defined once, │
│ and the column count changes at each breakpoint. │
│ │
└──────────────────────────────────────────────────────────────┘
Responsive Visibility
┌──────────────────────────────────────────────────────────────┐
│ RESPONSIVE VISIBILITY │
│ │
│ Full nav: class="hidden md:flex" │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Mobile: hidden │ │
│ │ md: flex ← visible │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ Menu button: class="flex md:hidden" │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Mobile: flex ← visible │ │
│ │ md: hidden │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ Together: │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Mobile: [Menu button] │ │
│ │ Desktop: [Home] [About] [Contact] │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ The mobile-first cascade handles both cases. The │
│ unprefixed class is the mobile state; the md: prefix │
│ overrides it for larger screens. │
│ │
└──────────────────────────────────────────────────────────────┘
Summary
| Item | Value |
|---|---|
| Mobile-first | Unprefixed utilities apply at all sizes; prefixed override at breakpoint and above |
| Default breakpoints | sm 640px, md 768px, lg 1024px, xl 1280px, 2xl 1536px |
| Prefix syntax | <breakpoint>:<utility>, e.g. md:flex |
| Cascade | Fixed order: sm → md → lg → xl → 2xl |
| Class order | Does not matter; breakpoint order determines the cascade |
| Mobile-only | Unprefixed base + override at sm: or md: |
| Desktop-only | hidden + md:block or lg:block |
| Responsive grid | grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 |
| Stack to spread | flex-col md:flex-row |
| Viewport meta | Required for responsive design to work |
Key takeaways:
- Tailwind is mobile-first. The unprefixed utility is the mobile style. Every prefixed utility is an enhancement at that breakpoint and larger. There is no “mobile-only” prefix — mobile is the default.
- Breakpoint prefixes are the entire responsive API. Every utility accepts a prefix. There are no separate responsive classes to learn. The prefix is the only new concept.
- The cascade is determined by breakpoint order, not class order.
md:flex lg:gridis the same aslg:grid md:flex. Larger breakpoints override smaller ones. - Write mobile first, then add breakpoints. The base layout is the simplest. Each breakpoint adds complexity rather than removing it. This produces cleaner, more maintainable responsive code.
- One breakpoint can cover a range.
md:flexapplies atmd,lg,xl, and2xlunless a larger breakpoint overrides it. You do not need to repeat the utility at every breakpoint. - Stacking and spreading is the most common pattern.
flex-colon mobile andmd:flex-rowon desktop covers most layout changes. - Responsive visibility uses the unprefixed base.
hidden md:blockhides on mobile and shows atmd.block md:hiddenshows on mobile and hides atmd. - The viewport meta tag is required. Without
<meta name="viewport" content="width=device-width, initial-scale=1">, the browser renders the page at desktop width and scales it down, and the breakpoints do not apply as expected.
Remember: Tailwind’s responsive system is a naming convention, not a separate API. Every utility you already know can be prefixed with a breakpoint, and the prefix means “at this breakpoint and above.” The mobile-first cascade means the unprefixed class is the baseline, and each prefixed group is a layer on top. This inverts the traditional desktop-first approach: instead of writing desktop styles and overriding for mobile, you write mobile styles and enhance for desktop. The result is simpler code, a predictable cascade, and a layout that adapts from the smallest screen upward. The breakpoints are fixed and consistent, the prefixes are the same across every utility, and the only rule to remember is that larger breakpoints win. Write the mobile layout first, add a breakpoint when the layout needs to change, and let the cascade do the rest.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!