Learn
🤖 AI Hub 📰 News 📖 Dictionary 🧰 Resources
Grow
💼 Jobs 🚀 Community 🏆 Challenges
Explore by Stage
🌑 Zero 📚 Learn 🔧 Practice 🏗 Build 🚀 Launch 💰 Earn
Account
Login Sign Up
🏗️HTML 🎨CSS ⚡JavaScript 🐙Git & GitHub ⚛️React Soon 📘TypeScript Soon 🐍Python 🗄️Database & SQL Soon 🌐Web Development Soon ☁️Cloud & DevOps Soon 🤖AI & ML Soon 📄Resume Prep Soon 🎤Interview Prep Soon 💼Freelancing Soon 🚀SaaS & Side Projects Soon 🤖Automation Soon
Advanced 🕑 19 min read 👁 4 views 📅 Oct 21, 2026

Responsive Layout Patterns That Work on Every Screen

Learn the responsive patterns professionals use every day: fluid containers, stack to columns, sidebars, auto-fit card grids, sticky footers, fluid type and touch-friendly sizes, built for a real restaurant website.

One Restaurant, Three Screens

Imran's family runs Ruchi Biryani House in Hyderabad. His cousin built them a website on a big laptop, and it looked lovely there. Then Imran opened it on his father's budget Android phone. The menu was cut off on the right, the text was tiny, and the "Order" button was so small that his father kept tapping the wrong link.

Most of the restaurant's customers find it on a phone, while standing at a bus stop or sitting in an auto. Some use a tablet at home, and the office crowd orders lunch from a laptop. One website has to work on all three. That is what responsive design means: the same HTML and CSS adjust to the size of the screen.

You already know the tools: media queries, Flexbox and Grid. This lesson shows the patterns that professionals build with those tools again and again.

Think Mobile First

Mobile first means you write the CSS for the smallest screen first, with no media query. Then you add min-width media queries to improve the layout as the screen gets wider.

Why this order? Three reasons:

  • Small screens need the simplest layout. Usually that is one column, which is how HTML flows anyway. You write less CSS.
  • Adding is easier than undoing. Going from one column to three is a small addition. Going from three columns back to one means overriding many rules.
  • It matches your users. In India, most people browse on phones, so the phone layout deserves to be the default, not an afterthought.
Every responsive page needs <meta name="viewport" content="width=device-width, initial-scale=1"> in the head. Without it, phones pretend the screen is about 980px wide and shrink the whole page, so your media queries never fire.

Pattern 1: The Fluid Container

Almost every page puts its content in a centred box called a container. It should fill a phone screen (with a small gap at the sides) but stop growing on a wide laptop, because lines of text that run across a 1500px screen are hard to read.

There are two common ways to write it. The first uses max-width and side padding. The second uses min(), a CSS function that picks the smaller of its values. width: min(100% - 32px, 900px) means "full width minus 32px, but never more than 900px".

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  body { margin: 0; font-family: system-ui, sans-serif; background: #f4efe6; }

  /* Way 1: max-width plus side padding */
  .container-a {
    max-width: 900px;
    margin: 0 auto;
    padding: 0 16px;
    background: #fff7e8;
  }

  /* Way 2: the same idea in one line with min() */
  .container-b {
    width: min(100% - 32px, 900px);
    margin-inline: auto;
    background: #e8f4ff;
  }
</style>
</head>
<body>
  <div class="container-a"><p>Ruchi Biryani House: max-width and padding.</p></div>
  <div class="container-b"><p>Ruchi Biryani House: width with min().</p></div>
</body>
</html>

Both give the same result. The min() version keeps the padding free for other uses. You will learn more about min(), max() and clamp() in the Modern CSS lesson.

Pattern 2: Stack, Then Columns

This is the most common responsive pattern. On a phone, the boxes stack in one column. Above a certain width, they sit side by side. Notice that the mobile layout needs no media query at all. Only the wider layout does.

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  body { margin: 0; font-family: system-ui, sans-serif; }

  /* Mobile first: one column, no media query needed */
  .features {
    display: grid;
    gap: 16px;
    padding: 16px;
  }
  .feature { background: #fff3e0; padding: 16px; border-radius: 10px; }

  /* Wider screens: three columns */
  @media (min-width: 700px) {
    .features { grid-template-columns: repeat(3, 1fr); }
  }
</style>
</head>
<body>
  <section class="features">
    <div class="feature"><h3>Dum Biryani</h3><p>Slow cooked in a sealed pot.</p></div>
    <div class="feature"><h3>Home Delivery</h3><p>Within 5 km of the restaurant.</p></div>
    <div class="feature"><h3>Family Hall</h3><p>Seats up to 40 guests.</p></div>
  </section>
</body>
</html>

How do you choose the breakpoint (the 700px)? Do not pick it from a list of phone models. Make the window slowly wider and add the breakpoint where the layout starts to look empty or stretched. The content decides, not the device.

Pattern 3: The Sidebar Layout

A sidebar sits beside the main content on wide screens and moves above it on small screens. You can do this with a media query, but Flexbox can do it on its own with flex-wrap.

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  body { margin: 0; font-family: system-ui, sans-serif; }

  .with-sidebar {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    padding: 16px;
  }
  .sidebar {
    flex: 1 1 200px;     /* happy at 200px, can grow */
    background: #fdecea;
    padding: 12px;
  }
  .main {
    flex: 999 1 320px;   /* takes almost all the extra space */
    background: #eef6ee;
    padding: 12px;
  }
</style>
</head>
<body>
  <div class="with-sidebar">
    <aside class="sidebar">
      <h3>Categories</h3>
      <p>Biryani, Kebabs, Desserts</p>
    </aside>
    <main class="main">
      <h3>Today's Menu</h3>
      <p>Make the result window narrow. When there is no room for 200px plus 320px, the sidebar drops above the menu by itself. No media query needed.</p>
    </main>
  </div>
</body>
</html>

Here is the "why". The sidebar wants 200px and the main area wants 320px. While the row has at least 520px plus the gap, they fit side by side. The huge flex-grow value of 999 on .main means it takes nearly all the extra space, so the sidebar stays close to 200px. When the row is too narrow, Flexbox wraps the main area to a new line, and each item then fills the full width. The layout responds to its own space, not to the screen size.

With Grid, the same layout is grid-template-columns: 220px 1fr inside a media query, as you saw in the CSS Grid Layouts lesson.

Pattern 4: The Self-Adjusting Card Grid

Menus, product lists and photo galleries are all grids of cards. This one line creates as many columns as fit, with no media queries:

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  body { margin: 0; font-family: system-ui, sans-serif; background: #faf7f2; }

  .menu-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
    gap: 16px;
    padding: 16px;
  }
  .dish {
    background: #fff;
    border: 1px solid #e6dccb;
    border-radius: 10px;
    padding: 16px;
  }
  .dish p { margin: 4px 0 0; color: #8a5a00; font-weight: bold; }
</style>
</head>
<body>
  <div class="menu-grid">
    <div class="dish"><h3>Chicken Biryani</h3><p>&#8377;260</p></div>
    <div class="dish"><h3>Veg Biryani</h3><p>&#8377;190</p></div>
    <div class="dish"><h3>Mirchi ka Salan</h3><p>&#8377;90</p></div>
    <div class="dish"><h3>Double ka Meetha</h3><p>&#8377;110</p></div>
    <div class="dish"><h3>Raita</h3><p>&#8377;40</p></div>
  </div>
</body>
</html>

Read repeat(auto-fit, minmax(min(100%, 180px), 1fr)) from the inside out:

PartMeaning
minmax(180px, 1fr)Each column is at least 180px and shares the extra space equally.
auto-fitFit as many columns as the row allows. Empty tracks collapse, so the cards stretch.
min(100%, 180px)On a very narrow screen (below 180px), use 100% instead, so nothing overflows.

Pattern 5: Header, Main, Footer

The classic "holy grail" page has a header at the top, a footer at the bottom and the main content in between. A common problem: on a short page, the footer floats up into the middle of the screen. Three grid rows fix it:

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  body {
    margin: 0;
    min-height: 100vh;
    display: grid;
    grid-template-rows: auto 1fr auto;   /* header, main, footer */
    font-family: system-ui, sans-serif;
  }
  header, footer { background: #7a2e0e; color: #fff; padding: 16px; }
  main { padding: 16px; }
</style>
</head>
<body>
  <header>Ruchi Biryani House</header>
  <main>
    <p>Only one line of content here, but the footer still sits at the bottom of the screen.</p>
  </main>
  <footer>Open daily, 12 noon to 11 PM</footer>
</body>
</html>

auto 1fr auto means the header and footer take only the height they need, and the main area takes all the rest. Because the body is at least the full screen height, the footer is pushed to the bottom.

Responsive Images and Fluid Type

Images have a fixed size by default, so a 1200px photo overflows a 360px phone. The rule max-width: 100%; height: auto; lets the image shrink inside its box while keeping its shape. Put it in your base styles for every project.

Text can be fluid too. clamp(min, preferred, max) picks the preferred value but keeps it between the minimum and maximum. For headings, a preferred value like 1.2rem + 3vw grows with the screen width (vw is 1% of the viewport width, as you saw in the CSS Units lesson). Adding a rem part keeps the text zoomable for people who set a larger font size.

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  body { margin: 0; padding: 16px; font-family: system-ui, sans-serif; }

  img {
    max-width: 100%;   /* never wider than its box */
    height: auto;      /* keep the shape */
    display: block;
    border-radius: 10px;
  }

  h1 {
    /* at least 1.75rem, grows with the screen, at most 3rem */
    font-size: clamp(1.75rem, 1.2rem + 3vw, 3rem);
    margin: 16px 0 8px;
  }
  p { font-size: clamp(1rem, 0.95rem + 0.3vw, 1.125rem); line-height: 1.6; }
</style>
</head>
<body>
  <img src="https://picsum.photos/1200/500" alt="Plates of food on a table">
  <h1>Hyderabadi Dum Biryani</h1>
  <p>Resize the result window. The photo and the heading both shrink and grow smoothly, with no media query at all.</p>
</body>
</html>

Touch-Friendly Sizes

A mouse pointer is tiny and precise. A finger is not. Accessibility guidelines recommend that anything you tap is at least about 44 by 44 CSS pixels. Links in a row also need some space between them. A simple way to achieve this is to give links and buttons display: inline-block, a min-height of 44px and enough padding. Also never rely on :hover to show important information, because there is no hover on a touch screen.

Testing in DevTools Device Mode

You do not need ten phones to test. In Chrome or Edge, press F12 (or Cmd + Option + I on a Mac), then click the device toolbar icon or press Ctrl + Shift + M. Now you can:

  • Pick a phone size from the list, or choose Responsive and drag the edge to any width.
  • Rotate to landscape with the rotate icon.

Drag slowly from 320px up to 1400px and watch for three things: anything that overflows sideways, text that becomes too small, and lines that become too long. Device mode is a close copy, not a perfect one, so also open the site on a real phone before you launch.

Real-Life Example: The Ruchi Biryani House Home Page

Here is a small version of Imran's fixed website. It combines every pattern: a fluid container, a header that wraps, the header/main/footer grid, a fluid heading, a responsive image, an intro that becomes two columns above 800px, an auto-fit menu grid and 44px touch targets.

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  * { box-sizing: border-box; }
  body {
    margin: 0;
    min-height: 100vh;
    display: grid;
    grid-template-rows: auto 1fr auto;
    font-family: system-ui, sans-serif;
    color: #2b1d12;
    background: #faf7f2;
  }
  .container { width: min(100% - 32px, 1000px); margin-inline: auto; }

  .site-header { background: #7a2e0e; color: #fff; }
  .site-header .container {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding-block: 8px;
  }
  .logo { font-weight: bold; font-size: 1.2rem; }
  .nav a {
    display: inline-block;
    min-height: 44px;           /* touch friendly */
    padding: 12px 10px;
    color: #fff;
    text-decoration: none;
  }

  h1 { font-size: clamp(1.75rem, 1.2rem + 3vw, 2.75rem); margin: 24px 0 8px; }
  .hero-img { width: 100%; height: auto; display: block; border-radius: 12px; }

  .menu-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
    gap: 16px;
    margin-block: 24px;
  }
  .dish { background: #fff; border: 1px solid #e6dccb; border-radius: 10px; padding: 16px; }
  .dish h3 { margin: 0 0 4px; }

  .btn {
    display: inline-block;
    min-height: 44px;
    padding: 12px 20px;
    background: #d35400;
    color: #fff;
    border-radius: 8px;
    text-decoration: none;
    font-weight: bold;
  }
  .site-footer { background: #2b1d12; color: #f4e6d4; padding-block: 16px; }

  @media (min-width: 800px) {
    .intro { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; align-items: center; }
  }
</style>
</head>
<body>
  <header class="site-header">
    <div class="container">
      <div class="logo">Ruchi Biryani House</div>
      <nav class="nav"><a href="#menu">Menu</a><a href="#visit">Visit</a><a href="#order">Order</a></nav>
    </div>
  </header>

  <main class="container">
    <section class="intro">
      <img class="hero-img" src="https://picsum.photos/800/500" alt="A table full of food">
      <div>
        <h1>Biryani the old Hyderabad way</h1>
        <p>Family recipes, slow cooked every morning since 2004.</p>
        <a class="btn" href="#order">Order for pickup</a>
      </div>
    </section>

    <section id="menu" class="menu-grid">
      <div class="dish"><h3>Chicken Biryani</h3><p>&#8377;260</p></div>
      <div class="dish"><h3>Mutton Biryani</h3><p>&#8377;340</p></div>
      <div class="dish"><h3>Veg Biryani</h3><p>&#8377;190</p></div>
      <div class="dish"><h3>Double ka Meetha</h3><p>&#8377;110</p></div>
    </section>
  </main>

  <footer class="site-footer">
    <div class="container">Open daily, 12 noon to 11 PM. Write to us: hello@example.com</div>
  </footer>
</body>
</html>

Try these changes:

  1. Open the result in DevTools device mode and switch between a small phone, a tablet and a laptop size.
  2. Change the menu card minimum from 200px to 260px and see how the number of columns changes.
  3. Move the intro breakpoint from 800px to 600px. At what width does it start to look too cramped?

Common Mistakes

  • Fixed pixel widths. A width: 960px box is wider than every phone, so the page scrolls sideways. Use max-width or min() instead, and let flex items wrap. Run the broken version, then the fixed one, in a narrow window:
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  .page { width: 960px; margin: 0 auto; background: #fff3e0; }
  .menu { display: flex; }
  .menu div { width: 320px; padding: 16px; }
</style>
</head>
<body>
  <div class="page">
    <div class="menu">
      <div>Chicken Biryani</div><div>Veg Biryani</div><div>Raita</div>
    </div>
  </div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  .page { width: min(100% - 32px, 960px); margin-inline: auto; background: #fff3e0; }
  .menu { display: flex; flex-wrap: wrap; gap: 8px; }
  .menu div { flex: 1 1 200px; padding: 16px; }
</style>
</head>
<body>
  <div class="page">
    <div class="menu">
      <div>Chicken Biryani</div><div>Veg Biryani</div><div>Raita</div>
    </div>
  </div>
</body>
</html>
  • Forgetting the viewport meta tag. The page looks like a shrunken desktop site on phones. Add the tag to every page.
  • Desktop first with max-width queries everywhere. You end up fighting your own rules. Write the phone layout first and add min-width queries.
  • Breakpoints for specific phone models. New phones arrive every month. Add a breakpoint where your content breaks, not where a device starts.
  • Tiny tap targets. Links of 14px text with no padding are hard to tap. Give them padding and a 44px minimum height.

Practice Task: A Responsive Photo Gallery Page

Ruchi Biryani House wants a gallery page. Complete the TODO comments in the starter code so the page works from a small phone to a laptop.

  • The footer stays at the bottom even when the content is short.
  • The content is never wider than 900px and has a 16px gap at each side on phones.
  • The gallery shows one column on a phone and more columns on wider screens, with no media query.
  • Images never overflow, and the heading size is fluid.
  • Nav links are at least 44px tall.
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  * { box-sizing: border-box; }
  body { margin: 0; font-family: system-ui, sans-serif; }

  /* TODO 1: make the page a header / main / footer grid (footer at the bottom) */

  /* TODO 2: a fluid .container: never wider than 900px, 16px gap at each side */

  /* TODO 3: .gallery as a card grid with auto-fit and minmax (cards at least 160px) */

  /* TODO 4: images must never overflow their card */

  /* TODO 5: fluid h1 with clamp(), between 1.5rem and 2.5rem */

  /* TODO 6: nav links at least 44px tall */
</style>
</head>
<body>
  <header class="container"><nav><a href="#">Home</a> <a href="#">Gallery</a></nav></header>
  <main class="container">
    <h1>Our Kitchen in Pictures</h1>
    <div class="gallery">
      <figure><img src="https://picsum.photos/600/400?1" alt="Dish one"></figure>
      <figure><img src="https://picsum.photos/600/400?2" alt="Dish two"></figure>
      <figure><img src="https://picsum.photos/600/400?3" alt="Dish three"></figure>
      <figure><img src="https://picsum.photos/600/400?4" alt="Dish four"></figure>
    </div>
  </main>
  <footer class="container">Open daily, 12 noon to 11 PM</footer>
</body>
</html>
Show one possible answer (try it yourself first!)
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  * { box-sizing: border-box; }
  body {
    margin: 0;
    font-family: system-ui, sans-serif;
    min-height: 100vh;
    display: grid;
    grid-template-rows: auto 1fr auto;
  }
  .container { width: min(100% - 32px, 900px); margin-inline: auto; }

  .gallery {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr));
    gap: 12px;
  }
  .gallery figure { margin: 0; }
  img { max-width: 100%; height: auto; display: block; border-radius: 8px; }

  h1 { font-size: clamp(1.5rem, 1rem + 2.5vw, 2.5rem); }

  nav a {
    display: inline-block;
    min-height: 44px;
    padding: 12px 8px;
  }
</style>
</head>
<body>
  <header class="container"><nav><a href="#">Home</a> <a href="#">Gallery</a></nav></header>
  <main class="container">
    <h1>Our Kitchen in Pictures</h1>
    <div class="gallery">
      <figure><img src="https://picsum.photos/600/400?1" alt="Dish one"></figure>
      <figure><img src="https://picsum.photos/600/400?2" alt="Dish two"></figure>
      <figure><img src="https://picsum.photos/600/400?3" alt="Dish three"></figure>
      <figure><img src="https://picsum.photos/600/400?4" alt="Dish four"></figure>
    </div>
  </main>
  <footer class="container">Open daily, 12 noon to 11 PM</footer>
</body>
</html>

Key Takeaways

  • Write mobile-first CSS: the phone layout is the default, and min-width queries improve it for wider screens.
  • A fluid container is width: min(100% - 32px, 900px) with margin-inline: auto.
  • flex-wrap and repeat(auto-fit, minmax(...)) create layouts that respond to their own space without media queries.
  • grid-template-rows: auto 1fr auto keeps the footer at the bottom of short pages.
  • Use max-width: 100% for images, clamp() for fluid text and 44px tap targets for fingers.
  • Test by dragging the width slowly in DevTools device mode, then check on a real phone.

❓ Frequently Asked Questions

There is no official list. Start with no breakpoints, widen the window slowly and add one where the layout starts to look wrong. Many sites end up with two or three, often somewhere around 600px, 900px and 1200px.
Use Grid when you think in rows and columns together, such as a card grid or a full page layout. Use Flexbox for a single row or column of items, such as a nav bar or a sidebar that wraps. Most real pages use both.
Both create as many columns as fit. With auto-fit, empty columns collapse so the existing cards stretch to fill the row. With auto-fill, the empty columns stay, so a row with few cards keeps them at their minimum size.
It catches most layout problems, but it cannot copy real touch, real fonts or real phone speed exactly. Always open the finished site on at least one real phone.
Was this lesson helpful?

🎯 Finished this lesson?

🔗 Related Tutorials
🤖 Got a Doubt? Ask AI
Get instant answers in Hindi or English
🤖
Z2T Bot
Online
Ask me anything about this tutorial — I'm here! 👋