Responsive Design & Breakpoints
More than half of the people visiting a typical Indian website are on a phone, and the rest are on laptops, tablets and large monitors. A responsive page rearranges itself to suit every screen. In Tailwind you do this without writing media queries: you add a breakpoint prefix such as md: in front of any class.
In this lesson you will learn Tailwind's mobile-first rule, the default breakpoints, how to target a range of sizes, and how to add your own breakpoints. You will build a product grid and a navigation bar that change with the screen width.
Mobile first
Tailwind's breakpoints are mobile first. A class with no prefix applies at every screen size. A prefixed class applies at that breakpoint and wider.
<h1 class="text-2xl md:text-4xl lg:text-5xl">Learn to code in Lucknow</h1>Read it as: "2xl text everywhere; from the md width upwards, 4xl; from lg upwards, 5xl". So you design for the small screen first, then add prefixes to adjust things as space grows.
| Prefix | Minimum width | Typical device |
|---|---|---|
| (none) | 0 | Every screen, starting with phones |
sm: | 40rem (640px) | Large phones in landscape |
md: | 48rem (768px) | Tablets |
lg: | 64rem (1024px) | Laptops |
xl: | 80rem (1280px) | Desktops |
2xl: | 96rem (1536px) | Large monitors |
Behind the scenes, md:flex becomes a media query, @media (width >= 48rem) { ... }, around the normal flex rule.
Responsive pages also need this tag in the <head>, or phones pretend to be a desktop screen and shrink everything:
<meta name="viewport" content="width=device-width, initial-scale=1">A responsive grid
The most common pattern: one column on phones, more columns as space grows.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Responsive grid</title>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body class="bg-slate-100 p-4 md:p-8">
<h1 class="text-2xl font-bold md:text-4xl">Handloom sarees</h1>
<p class="mt-1 text-slate-600 md:text-lg">Woven in Chanderi, delivered across India.</p>
<div class="mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
<div class="rounded-xl bg-white p-4"><p class="font-semibold">Mint silk</p><p>₹3,499</p></div>
<div class="rounded-xl bg-white p-4"><p class="font-semibold">Rani pink</p><p>₹2,999</p></div>
<div class="rounded-xl bg-white p-4"><p class="font-semibold">Ivory gold</p><p>₹4,250</p></div>
<div class="rounded-xl bg-white p-4"><p class="font-semibold">Indigo cotton</p><p>₹1,899</p></div>
</div>
</body>
</html>Make the result narrow and then wide. The cards go from one column, to two at sm, to four at lg. The heading, paragraph and page padding also grow at md.
Showing and hiding by screen size
Combine hidden with a display class to show something only at some sizes. This is how a navigation bar switches between a phone menu button and a full row of links:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Responsive navbar</title>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body>
<header class="flex items-center justify-between bg-white px-4 py-3 shadow-sm">
<a href="#" class="text-lg font-bold text-sky-700">Kochi Coders</a>
<nav class="hidden gap-6 md:flex">
<a href="#" class="hover:text-sky-700">Courses</a>
<a href="#" class="hover:text-sky-700">Batches</a>
<a href="#" class="hover:text-sky-700">Contact</a>
</nav>
<button class="rounded-md border border-slate-300 px-3 py-1 md:hidden" aria-label="Open menu">Menu</button>
</header>
</body>
</html>The <nav> is hidden on small screens and becomes flex from md up. The "Menu" button does the opposite with md:hidden. A real menu button also needs a little JavaScript to open the links; the project lesson builds one.
Targeting a range
Sometimes a style should apply only below a size, or only between two sizes. Tailwind has max-* variants for that:
| Class | Applies when |
|---|---|
max-md:hidden | The screen is narrower than md (below 768px) |
md:max-lg:flex | From md up to, but not including, lg |
min-[400px]:flex | 400px and wider (a one-off breakpoint) |
max-[600px]:text-sm | Narrower than 600px |
<!-- Sticky bottom bar only on phones and small tablets -->
<div class="max-md:fixed max-md:inset-x-0 max-md:bottom-0 max-md:bg-white max-md:p-3">
<a href="#" class="block rounded-lg bg-sky-600 py-2 text-center text-white">Book a free demo</a>
</div>Use ranges sparingly. Mobile-first classes are easier to read, because each larger breakpoint only adds what changes.
Custom breakpoints
Breakpoints are theme variables, so you change them in CSS with @theme. Add a new one, change an existing one, or remove one:
@import "tailwindcss";
@theme {
--breakpoint-xs: 30rem; /* new: xs: from 480px */
--breakpoint-3xl: 120rem; /* new: 3xl: from 1920px */
--breakpoint-2xl: initial; /* remove the 2xl breakpoint */
}Use rem values like the defaults, so breakpoints stay correct when someone increases their browser's font size. Tailwind sorts breakpoints by size, so xs: works before sm: automatically. See Customising with @theme for the full theme system.
The container class
container sets width: 100% and a max-width equal to the current breakpoint, so the content grows in steps. In Tailwind 4 it does not centre itself or add padding, so you add those:
<div class="container mx-auto px-4">...</div>Many developers prefer a fixed cap instead, such as mx-auto max-w-7xl px-4, which grows smoothly rather than in jumps. Both are fine; pick one for the whole site.
Common mistakes
- Using
sm:for phones. Unprefixed classes are the phone styles; prefixes are for larger screens. - Missing viewport tag. Without it, phones render the desktop layout zoomed out.
- Repeating the same value.
p-4 md:p-4 lg:p-4is the same asp-4. A prefixed class is only needed when the value changes. - Designing desktop first. Squeezing a desktop layout onto a phone leads to many
max-*overrides. Start small, then add.
Key points
- Classes without a prefix apply everywhere;
sm:,md:,lg:,xl:and2xl:apply from that width upwards. - The default breakpoints are 40rem, 48rem, 64rem, 80rem and 96rem (640px to 1536px).
- Show and hide parts with pairs like
hidden md:flexandmd:hidden. max-md:targets screens below a breakpoint, andmd:max-lg:targets a range.- Add or change breakpoints with
--breakpoint-*variables in@theme. containercaps width per breakpoint but needsmx-autoand padding in v4.
Exercise
Make a "Meet our teachers" section for a school in Rohtak. It should show teacher cards in one column on phones, two columns from sm, and three from lg. The section heading should be centred on phones but left-aligned from md. Each card shows an avatar ({{samples}}/avatar.svg), a name and a subject.
Show solution
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Our teachers</title>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body class="bg-slate-50 p-4 md:p-8">
<h2 class="text-center text-2xl font-bold md:text-left">Meet our teachers</h2>
<div class="mt-6 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
<div class="flex items-center gap-3 rounded-xl bg-white p-4">
<img src="https://course.ethicscomputer.in/assets/samples/avatar.svg" alt="" class="size-12 rounded-full">
<div><p class="font-semibold">Mrs Meera Hooda</p><p class="text-sm text-slate-600">Mathematics</p></div>
</div>
<div class="flex items-center gap-3 rounded-xl bg-white p-4">
<img src="https://course.ethicscomputer.in/assets/samples/avatar.svg" alt="" class="size-12 rounded-full">
<div><p class="font-semibold">Mr Kabir Dahiya</p><p class="text-sm text-slate-600">Physics</p></div>
</div>
<div class="flex items-center gap-3 rounded-xl bg-white p-4">
<img src="https://course.ethicscomputer.in/assets/samples/avatar.svg" alt="" class="size-12 rounded-full">
<div><p class="font-semibold">Ms Isha Malik</p><p class="text-sm text-slate-600">English</p></div>
</div>
</div>
</body>
</html>The grid starts as one column (no prefix), then sm:grid-cols-2 and lg:grid-cols-3 add columns. text-center md:text-left centres the heading on phones only.
Quick Quiz
1. On which screens does md:grid-cols-3 apply?
Breakpoint prefixes are mobile first: they apply at that width and above.
2. You want text centred on phones and left-aligned on larger screens. Which classes are right?
The unprefixed class styles phones, and the prefixed class changes it from that breakpoint up.
3. Which class hides an element only on screens below the md breakpoint?
max-md: applies when the width is less than 48rem; md:hidden would hide it on larger screens instead.
4. How do you add a new 3xl breakpoint in Tailwind v4?
In v4, breakpoints are theme variables defined in CSS with @theme.
Learn Tailwind CSS with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
