This page is a complete responsive website example: one index.html file you can copy, save, and open in a browser. The page changes its layout to suit the screen viewing it — a phone, a tablet, or a desktop — using the three building blocks of responsive web design: the viewport meta tag, a fluid layout, and media queries. It is part of the code examples library. The single-file version of the same idea without the responsive layer is the HTML website example, and a whole site made of plain files is the static website example.

The complete responsive website example

Below is the whole site in a single index.html file: a small business site for a fictional landscaping company called Greenwing Landscaping. It is self-contained — the styles and the small amount of JavaScript for the mobile menu live in the same file, and the images are inline SVG, so it runs offline with nothing installed.

Copy it, save it as index.html, and open that file in a browser. Drag the window narrower and wider and watch the layout change: at phone width the navigation collapses into a menu button, and the services cards reflow from three across to one per row.

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Greenwing Landscaping — Lawn Care &amp; Garden Design</title>
  <meta name="description" content="Greenwing Landscaping designs and maintains gardens, lawns, and outdoor spaces in Rivervale. Free estimates, weekly care plans, and seasonal planting." />
  <style>
    :root {
      --ink: #223022;
      --muted: #5f6b5a;
      --accent: #3b6b45;
      --paper: #f7f5ef;
      --line: #dfe4d8;
    }

    * { box-sizing: border-box; }

    body {
      margin: 0;
      font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
      color: var(--ink);
      background: var(--paper);
      line-height: 1.6;
    }

    img { max-width: 100%; height: auto; display: block; }

    .skip-link {
      position: absolute;
      left: -999px;
      top: 0;
      background: #111827;
      color: #ffffff;
      padding: 8px 14px;
      z-index: 10;
    }
    .skip-link:focus { left: 0; }

    .container {
      width: 100%;
      max-width: 68rem;
      margin: 0 auto;
      padding: 0 1.25rem;
    }

    header { background: var(--accent); color: #ffffff; }
    .header-inner {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-between;
      gap: 0.75rem 1rem;
      padding: 0.9rem 1.25rem;
    }
    .brand { margin: 0; font-size: 1.25rem; font-weight: 700; }

    .nav-toggle {
      display: inline-flex;
      align-items: center;
      gap: 0.5rem;
      border: 0;
      border-radius: 6px;
      padding: 0.5rem 0.75rem;
      font: inherit;
      color: #ffffff;
      background: #2c5234;
      cursor: pointer;
    }
    .nav-toggle span { font-size: 1.05rem; line-height: 1; }

    nav { display: none; order: 10; width: 100%; }
    nav.open { display: block; }
    nav ul { list-style: none; margin: 0; padding: 0; }
    nav a {
      display: block;
      padding: 0.6rem 0;
      border-top: 1px solid rgba(255, 255, 255, 0.15);
      color: #eaf3ec;
      text-decoration: none;
    }
    nav a:hover, nav a:focus { color: #ffffff; text-decoration: underline; }

    .hero {
      background: linear-gradient(160deg, #2c5234, #3b6b45);
      color: #ffffff;
      padding: 3.5rem 0 3rem;
    }
    .hero h1 {
      margin: 0 0 1rem;
      font-size: clamp(2rem, 5vw, 3.25rem);
      line-height: 1.1;
    }
    .hero p { margin: 0 0 1.5rem; max-width: 40rem; font-size: 1.1rem; }
    .hero img { border-radius: 12px; margin-top: 1.5rem; }
    .btn {
      display: inline-block;
      border-radius: 8px;
      padding: 0.7rem 1.25rem;
      background: #f2c14e;
      color: #223022;
      font-weight: 700;
      text-decoration: none;
    }
    .btn:hover, .btn:focus { background: #eab02f; }

    section { padding: 3rem 0; }
    h2 { margin: 0 0 1.25rem; color: var(--accent); font-size: clamp(1.5rem, 3vw, 2rem); }

    .cards {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
      gap: 1.25rem;
      margin: 0;
      padding: 0;
      list-style: none;
    }
    .card {
      border: 1px solid var(--line);
      border-radius: 12px;
      padding: 1.25rem;
      background: #ffffff;
    }
    .card img { border-radius: 8px; margin-bottom: 0.75rem; }
    .card h3 { margin: 0 0 0.5rem; }
    .card p { margin: 0; }

    .hours {
      max-width: 32rem;
      border: 1px solid var(--line);
      border-radius: 12px;
      padding: 1.25rem;
      background: #ffffff;
    }
    .hours ul { list-style: none; margin: 0; padding: 0; }
    .hours li {
      display: flex;
      justify-content: space-between;
      padding: 0.4rem 0;
      border-bottom: 1px solid var(--line);
    }
    .hours li:last-child { border-bottom: 0; }

    footer {
      background: var(--ink);
      color: #c9d4c9;
      padding: 2.5rem 0 1.5rem;
    }
    .footer-cols {
      display: grid;
      grid-template-columns: 1fr;
      gap: 1.5rem;
    }
    footer h3 { margin: 0 0 0.5rem; color: #ffffff; }
    footer p { margin: 0; }
    footer a { color: #eaf3ec; }
    .footer-base {
      margin-top: 1.5rem;
      padding-top: 1rem;
      border-top: 1px solid rgba(255, 255, 255, 0.15);
      font-size: 0.9rem;
    }

    @media (min-width: 40rem) {
      .nav-toggle { display: none; }
      nav, nav.open { display: block; order: 0; width: auto; }
      nav ul { display: flex; gap: 1.5rem; }
      nav a { padding: 0; border-top: 0; }
      .footer-cols { grid-template-columns: repeat(3, 1fr); }
    }

    @media (min-width: 62rem) {
      .hero-inner {
        display: grid;
        grid-template-columns: 1fr 1fr;
        align-items: center;
        gap: 3rem;
      }
      .hero img { margin-top: 0; }
    }
  </style>
  <noscript>
    <style>
      nav { display: block; }
      .nav-toggle { display: none; }
    </style>
  </noscript>
</head>
<body>
  <a class="skip-link" href="#main">Skip to main content</a>

  <header>
    <div class="container header-inner">
      <p class="brand">Greenwing Landscaping</p>
      <button class="nav-toggle" id="nav-toggle" type="button" aria-expanded="false" aria-controls="nav-menu">
        <span aria-hidden="true">&#9776;</span> Menu
      </button>
      <nav id="nav-menu" aria-label="Primary">
        <ul>
          <li><a href="#services">Services</a></li>
          <li><a href="#about">About</a></li>
          <li><a href="#hours">Hours</a></li>
          <li><a href="#contact">Contact</a></li>
        </ul>
      </nav>
    </div>
  </header>

  <main id="main">
    <div class="hero">
      <div class="container hero-inner">
        <div>
          <h1>Outdoor spaces, cared for year-round</h1>
          <p>Greenwing Landscaping designs and maintains gardens, lawns, and patios across Rivervale. Free estimates, weekly care plans, and seasonal planting.</p>
          <a class="btn" href="#contact">Request an estimate</a>
        </div>
        <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0%200%20800%20400'%3E%3Crect width='800' height='400' fill='%232c5234'/%3E%3Ccircle cx='640' cy='90' r='60' fill='%23f2c14e'/%3E%3Crect y='300' width='800' height='100' fill='%233b6b45'/%3E%3C/svg%3E" alt="A landscaped garden path with neat hedges and a flowering border under a bright sky" />
      </div>
    </div>

    <section id="services" class="container">
      <h2>Services</h2>
      <ul class="cards">
        <li class="card">
          <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0%200%20800%20400'%3E%3Crect width='800' height='400' fill='%234e7c3f'/%3E%3Crect x='0' width='160' height='400' fill='%235f8f4c'/%3E%3Crect x='320' width='160' height='400' fill='%235f8f4c'/%3E%3Crect x='640' width='160' height='400' fill='%235f8f4c'/%3E%3C/svg%3E" alt="A freshly mown lawn with clean striped cuts" />
          <h3>Lawn care</h3>
          <p>Weekly mowing, edging, and fertilization from March to October.</p>
        </li>
        <li class="card">
          <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0%200%20800%20400'%3E%3Crect width='800' height='400' fill='%234a3527'/%3E%3Ccircle cx='150' cy='200' r='48' fill='%23e0577a'/%3E%3Ccircle cx='360' cy='140' r='42' fill='%23f2c14e'/%3E%3Ccircle cx='580' cy='220' r='50' fill='%2384b6f4'/%3E%3Ccircle cx='700' cy='110' r='36' fill='%23c48be0'/%3E%3C/svg%3E" alt="A small ornamental garden bed in bloom with colorful flowers" />
          <h3>Garden design</h3>
          <p>Planting plans and beds designed for your light, soil, and climate.</p>
        </li>
        <li class="card">
          <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0%200%20800%20400'%3E%3Crect width='800' height='400' fill='%23b8b2a4'/%3E%3Crect y='0' width='800' height='110' fill='%23304927'/%3E%3Crect x='110' y='190' width='190' height='190' fill='%23a49e90'/%3E%3Crect x='350' y='140' width='210' height='240' fill='%23a49e90'/%3E%3Crect x='610' y='210' width='150' height='170' fill='%23a49e90'/%3E%3C/svg%3E" alt="A stone patio with a trimmed hedge along the back" />
          <h3>Patios &amp; hardscaping</h3>
          <p>Stone patios, paths, and retaining walls built to last.</p>
        </li>
        <li class="card">
          <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0%200%20800%20400'%3E%3Crect width='800' height='400' fill='%235f8f4c'/%3E%3Cpath d='M0 280 L400 90 L800 280 Z' fill='%23e0577a'/%3E%3Cpath d='M120 390 L400 240 L680 390 Z' fill='%23f2c14e'/%3E%3C/svg%3E" alt="A seasonal flower bed with tall tulips in red and yellow" />
          <h3>Seasonal planting</h3>
          <p>Spring bulbs, summer color, and autumn tidy-ups.</p>
        </li>
      </ul>
    </section>

    <section id="about" class="container">
      <h2>About</h2>
      <p>Greenwing has cared for gardens in Rivervale since 2014. Every plan is written out before work starts, and you approve it before anything is planted or dug.</p>
    </section>

    <section id="hours" class="container">
      <h2>Opening hours</h2>
      <div class="hours">
        <ul>
          <li><span>Monday – Friday</span><span>7:00 – 18:00</span></li>
          <li><span>Saturday</span><span>8:00 – 14:00</span></li>
          <li><span>Sunday</span><span>Closed</span></li>
        </ul>
      </div>
    </section>

    <section id="contact" class="container">
      <h2>Contact</h2>
      <address>
        92 River Lane, Rivervale<br />
        <a href="mailto:hello@greenwing.example">hello@greenwing.example</a><br />
        <a href="tel:+15035550142">(503) 555-0142</a>
      </address>
    </section>
  </main>

  <footer>
    <div class="container">
      <div class="footer-cols">
        <div>
          <h3>Greenwing Landscaping</h3>
          <p>Lawn care, garden design, and hardscaping in Rivervale.</p>
        </div>
        <div>
          <h3>Services</h3>
          <p><a href="#services">Lawn care</a> · <a href="#services">Garden design</a> · <a href="#services">Patios</a></p>
        </div>
        <div>
          <h3>Contact</h3>
          <p><a href="mailto:hello@greenwing.example">hello@greenwing.example</a></p>
        </div>
      </div>
      <p class="footer-base">&copy; 2026 Greenwing Landscaping. All rights reserved.</p>
    </div>
  </footer>

  <script>
    const toggle = document.getElementById("nav-toggle");
    const menu = document.getElementById("nav-menu");
    toggle.addEventListener("click", () => {
      const open = menu.classList.toggle("open");
      toggle.setAttribute("aria-expanded", String(open));
      toggle.querySelector("span").textContent = open ? "\u2715" : "\u2630";
    });
  </script>
</body>
</html>

What the example looks like

The sketch below shows the same page at two widths: a wide desktop window and a narrow phone window. In the desktop version the navigation is a horizontal row and the services sit three across; in the phone version the menu is a button and the cards stack one per row:

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<style>
  body { margin: 0; font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; background: #f3f4f6; padding: 24px; }
  .pair { display: flex; gap: 24px; align-items: flex-start; justify-content: center; flex-wrap: wrap; }
  .window { background: #fff; border-radius: 10px; box-shadow: 0 1px 3px rgba(0,0,0,.12); overflow: hidden; }
  .window.desktop { width: 460px; }
  .window.mobile { width: 210px; }
  .titlebar { display: flex; align-items: center; gap: 6px; padding: 8px 10px; background: #e5e7eb; }
  .dot { width: 9px; height: 9px; border-radius: 50%; }
  .r { background: #fca5a5; } .y { background: #fcd34d; } .g { background: #86efac; }
  .header { display: flex; align-items: center; justify-content: space-between; gap: 8px; background: #3b6b45; padding: 10px 14px; }
  .brand { color: #fff; font-size: 12px; }
  .nav { display: flex; gap: 12px; }
  .nav span { color: #eaf3ec; font-size: 10px; }
  .burger { color: #fff; font-size: 13px; }
  .hero { background: #2c5234; color: #fff; padding: 26px 14px; }
  .hero h1 { margin: 0 0 8px; font-size: 14px; line-height: 1.3; }
  .hero p { margin: 0 0 12px; font-size: 9px; line-height: 1.5; }
  .btn { display: inline-block; background: #f2c14e; color: #223022; font-size: 9px; padding: 5px 10px; border-radius: 6px; }
  .section { padding: 16px 14px; }
  .section h2 { font-size: 11px; margin: 0 0 10px; color: #3b6b45; }
  .cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
  .card { border: 1px solid #e5e7eb; border-radius: 6px; padding: 8px; }
  .photo { height: 40px; border-radius: 4px; margin-bottom: 6px; background: linear-gradient(#5f8f4c, #3b6b45); }
  .bar { height: 6px; background: #e5e7eb; border-radius: 3px; margin-bottom: 5px; }
  .bar.short { width: 60%; }
  .footer { background: #223022; color: #c9d4c9; text-align: center; padding: 12px; font-size: 9px; }
  .window.mobile .cards { grid-template-columns: 1fr; }
</style>
</head>
<body>
  <div class="pair">
    <div class="window desktop">
      <div class="titlebar"><span class="dot r"></span><span class="dot y"></span><span class="dot g"></span></div>
      <div class="header"><span class="brand">Greenwing Landscaping</span><div class="nav"><span>Services</span><span>About</span><span>Hours</span><span>Contact</span></div></div>
      <div class="hero"><h1>Outdoor spaces, cared for year-round</h1><p>Desktop sketch: a horizontal navigation and a two-column hero at 62rem and wider.</p><span class="btn">Request an estimate</span></div>
      <div class="section"><h2>Services</h2><div class="cards"><div class="card"><div class="photo"></div><div class="bar"></div><div class="bar short"></div></div><div class="card"><div class="photo"></div><div class="bar"></div><div class="bar short"></div></div><div class="card"><div class="photo"></div><div class="bar"></div><div class="bar short"></div></div></div></div>
      <div class="footer">&copy; 2026 Greenwing Landscaping</div>
    </div>
    <div class="window mobile">
      <div class="titlebar"><span class="dot r"></span><span class="dot y"></span><span class="dot g"></span></div>
      <div class="header"><span class="brand">Greenwing</span><span class="burger">&#9776;</span></div>
      <div class="hero"><h1>Outdoor spaces, cared for year-round</h1><p>Phone sketch: below 40rem the menu is a button, the hero stacks, and one card shows per row.</p><span class="btn">Request an estimate</span></div>
      <div class="section"><h2>Services</h2><div class="cards"><div class="card"><div class="photo"></div><div class="bar"></div><div class="bar short"></div></div></div></div>
      <div class="footer">&copy; 2026 Greenwing Landscaping</div>
    </div>
  </div>
</body>
</html>

The mockup is only a picture of the layout. The complete file in the section above is what produces it, and it reacts to the width of the real browser window as you resize it.

What makes a website responsive

Responsive web design is an approach, not a single technology. Plain HTML already reflows text to fit the window; responsive design is the CSS layer that turns that default behavior into a deliberate layout. A responsive page combines three ideas:

  1. A viewport meta tag, so phones render the page at their real width instead of a wide virtual viewport.
  2. A fluid layout built from relative units, so columns, images, and text grow and shrink with the screen.
  3. Media queries that apply new styles at chosen widths, called breakpoints.

Two modern companions complete the picture: fluid typography that scales smoothly with the viewport, and fluid images that never overflow their container. Every one of these appears in the example above; the next section points at the exact lines.

The techniques in the example

The viewport meta tag

The head starts with &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;. Mobile browsers assume a desktop-sized viewport — often 980px wide — unless this tag is present, then render the page there and zoom it out to fit the phone. width=device-width overrides that default so the page renders at the device's actual width and the media queries trigger at the right sizes. initial-scale=1 sets the starting zoom to 100%.

Keep the tag as-is. Do not add user-scalable=no or maximum-scale=1: both disable pinch zoom, which breaks accessibility for low-vision visitors.

Mobile-first base styles

The base CSS is written for the smallest screen first: one column, stacked content, and the navigation hidden behind a menu button. The media queries add complexity only for wider screens. This mobile-first ordering means a phone never has to undo a desktop layout, and it is the order most current guides recommend.

A fluid container

The page content sits inside .container, which is width: 100%; max-width: 68rem; margin: 0 auto;. On a phone it fills the width minus padding; on a wide monitor it stops growing at 68rem and centers. Nothing uses a fixed pixel width, so there is no width at which the page starts to scroll sideways.

A fluid grid

The services grid uses a fluid pattern that needs no media queries of its own:

css
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

minmax(240px, 1fr) means at least 240px wide and grow to share the row; auto-fit means put as many columns in a row as fit. The grid shows one card per row on a phone, two on a tablet, and three or more on a desktop, reflowing smoothly as the width changes. Flexible units like 1fr are why most of a responsive layout needs no pixel targets.

Media queries at rem breakpoints

The layout also makes two explicit switches:

css
@media (min-width: 40rem) { ... }
@media (min-width: 62rem) { ... }

A media query applies its rules only while its condition is true, so the min-width: 40rem block kicks in once the viewport is at least 640px wide. The breakpoints use rem rather than device pixel sizes, so they scale with the visitor's default font size, and they sit at the widths where the content starts to look cramped, not at the sizes of any particular phone. The example needs only two, because the fluid grid above already handles the card layout.

Fluid typography

The main heading scales continuously between a floor and a ceiling:

css
.hero h1 {
  font-size: clamp(2rem, 5vw, 3.25rem);
}

clamp() picks a value between the first and last numbers: at least 2rem, growing with the viewport (5vw), and never above 3.25rem. Headings set this way stay readable at every width without a media query for each size. The section headings use the same idea with smaller values.

Fluid images

This single rule keeps images from overflowing their containers:

css
img {
  max-width: 100%;
  height: auto;
}

An image is never wider than the column holding it, and height: auto keeps its proportions. The example's images are inline SVG data URIs so they travel inside the one file, but the same rule applies to ordinary photo files. Sites that want different crops on different screens can add srcset and sizes on top; the website basics library covers the details.

The mobile navigation

Below the 40rem breakpoint the menu button is shown and the navigation is hidden; above it the button disappears and the links appear in a row. The button toggles an open class on the nav and keeps screen readers in sync through aria-expanded:

js
const toggle = document.getElementById("nav-toggle");
const menu = document.getElementById("nav-menu");
toggle.addEventListener("click", () => {
  const open = menu.classList.toggle("open");
  toggle.setAttribute("aria-expanded", String(open));
  toggle.querySelector("span").textContent = open ? "\u2715" : "\u2630";
});

The button is a real &lt;button&gt; element, so it works with the keyboard, and a small noscript block in the file makes the navigation visible even when JavaScript is disabled.

The breakpoints at a glance

BreakpointConditionWhat changes
Base (mobile first)Below 40rem (below 640px)Single column; the services show one card per row; the menu button is visible and the navigation is hidden
First breakpoint@media (min-width: 40rem) — 640px and upThe menu button disappears and the navigation becomes a horizontal row; the footer splits into three columns
Second breakpoint@media (min-width: 62rem) — 992px and upThe hero becomes two columns with the image beside the headline

The services grid is not in this table because it reflows continuously: auto-fit and minmax handle that section without a breakpoint of its own.

How the layout changes

The diagram below draws the same page at the three width ranges the example targets. Each sketch shows the same elements — header with navigation, hero, content cards, footer — so you can see what moves when each media query kicks in:

svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 280" font-family="ui-monospace, Menlo, Consolas, monospace" font-size="10">
  <rect width="900" height="280" fill="#ffffff" />
  <text x="150" y="20" text-anchor="middle" font-weight="bold" fill="#223022">Below 40rem</text>
  <text x="150" y="32" text-anchor="middle" fill="#5f6b5a">one column</text>
  <rect x="90" y="42" width="120" height="200" rx="6" fill="#f7f5ef" stroke="#dfe4d8" />
  <rect x="90" y="42" width="120" height="16" rx="6" fill="#3b6b45" />
  <rect x="196" y="46" width="8" height="8" rx="2" fill="#ffffff" />
  <rect x="98" y="66" width="104" height="42" rx="4" fill="#2c5234" />
  <rect x="98" y="74" width="66" height="6" rx="3" fill="#ffffff" />
  <rect x="98" y="86" width="88" height="5" rx="2.5" fill="#ffffff" opacity="0.5" />
  <rect x="98" y="116" width="104" height="34" rx="4" fill="#ffffff" stroke="#dfe4d8" />
  <rect x="98" y="124" width="40" height="6" rx="3" fill="#3b6b45" />
  <rect x="98" y="136" width="84" height="5" rx="2.5" fill="#e5e7eb" />
  <rect x="98" y="158" width="104" height="34" rx="4" fill="#ffffff" stroke="#dfe4d8" />
  <rect x="98" y="166" width="40" height="6" rx="3" fill="#3b6b45" />
  <rect x="98" y="178" width="84" height="5" rx="2.5" fill="#e5e7eb" />
  <rect x="90" y="222" width="120" height="8" rx="4" fill="#223022" />
  <text x="450" y="20" text-anchor="middle" font-weight="bold" fill="#223022">40rem and up</text>
  <text x="450" y="32" text-anchor="middle" fill="#5f6b5a">nav and footer change</text>
  <rect x="330" y="42" width="240" height="200" rx="6" fill="#f7f5ef" stroke="#dfe4d8" />
  <rect x="330" y="42" width="240" height="16" rx="6" fill="#3b6b45" />
  <rect x="540" y="46" width="8" height="8" rx="2" fill="#ffffff" />
  <rect x="528" y="46" width="8" height="8" rx="2" fill="#ffffff" opacity="0.7" />
  <rect x="516" y="46" width="8" height="8" rx="2" fill="#ffffff" opacity="0.5" />
  <rect x="516" y="50" width="46" height="4" rx="2" fill="#ffffff" opacity="0.5" />
  <rect x="340" y="66" width="220" height="50" rx="4" fill="#2c5234" />
  <rect x="340" y="74" width="80" height="6" rx="3" fill="#ffffff" />
  <rect x="340" y="86" width="120" height="5" rx="2.5" fill="#ffffff" opacity="0.5" />
  <rect x="340" y="124" width="106" height="44" rx="4" fill="#ffffff" stroke="#dfe4d8" />
  <rect x="340" y="132" width="44" height="6" rx="3" fill="#3b6b45" />
  <rect x="340" y="144" width="86" height="5" rx="2.5" fill="#e5e7eb" />
  <rect x="454" y="124" width="106" height="44" rx="4" fill="#ffffff" stroke="#dfe4d8" />
  <rect x="454" y="132" width="44" height="6" rx="3" fill="#3b6b45" />
  <rect x="454" y="144" width="86" height="5" rx="2.5" fill="#e5e7eb" />
  <rect x="330" y="222" width="240" height="8" rx="4" fill="#223022" />
  <text x="760" y="20" text-anchor="middle" font-weight="bold" fill="#223022">62rem and up</text>
  <text x="760" y="32" text-anchor="middle" fill="#5f6b5a">hero becomes two columns</text>
  <rect x="640" y="42" width="240" height="200" rx="6" fill="#f7f5ef" stroke="#dfe4d8" />
  <rect x="640" y="42" width="240" height="16" rx="6" fill="#3b6b45" />
  <rect x="850" y="46" width="8" height="8" rx="2" fill="#ffffff" />
  <rect x="838" y="46" width="8" height="8" rx="2" fill="#ffffff" opacity="0.7" />
  <rect x="826" y="46" width="8" height="8" rx="2" fill="#ffffff" opacity="0.5" />
  <rect x="826" y="50" width="46" height="4" rx="2" fill="#ffffff" opacity="0.5" />
  <rect x="650" y="66" width="220" height="64" rx="4" fill="#2c5234" />
  <rect x="650" y="74" width="84" height="6" rx="3" fill="#ffffff" />
  <rect x="650" y="86" width="120" height="5" rx="2.5" fill="#ffffff" opacity="0.5" />
  <rect x="768" y="70" width="90" height="50" rx="4" fill="#5f8f4c" opacity="0.6" />
  <rect x="650" y="144" width="70" height="44" rx="4" fill="#ffffff" stroke="#dfe4d8" />
  <rect x="650" y="152" width="34" height="6" rx="3" fill="#3b6b45" />
  <rect x="650" y="164" width="54" height="5" rx="2.5" fill="#e5e7eb" />
  <rect x="728" y="144" width="70" height="44" rx="4" fill="#ffffff" stroke="#dfe4d8" />
  <rect x="728" y="152" width="34" height="6" rx="3" fill="#3b6b45" />
  <rect x="728" y="164" width="54" height="5" rx="2.5" fill="#e5e7eb" />
  <rect x="806" y="144" width="70" height="44" rx="4" fill="#ffffff" stroke="#dfe4d8" />
  <rect x="806" y="152" width="34" height="6" rx="3" fill="#3b6b45" />
  <rect x="806" y="164" width="54" height="5" rx="2.5" fill="#e5e7eb" />
  <rect x="640" y="222" width="240" height="8" rx="4" fill="#223022" />
</svg>

The wireframe is not code to copy — it is a diagram of how the example's layout behaves at each width range.

Responsive vs adaptive

Responsive is sometimes confused with adaptive design, and the two solve the same problem differently:

ResponsiveAdaptive
LayoutOne fluid layout that reflows at breakpointsSeveral fixed layouts
How the change happensThe same HTML and CSS serve everyone; media queries restyle the pageThe device is detected and one of the fixed layouts is served
Content between layoutsNever a duplicate; the same document resizesCan serve different markup per device
Typical use todayThe default approach for most sitesRare; usually only for experiences built for a specific device

A responsive site is a single file or a set of files that behaves well at any width — the approach the example on this page uses. A site that is not responsive simply shows the desktop layout scaled down on a phone, which is exactly what the viewport meta tag prevents.

Blank responsive starter

This is the same skeleton with the content removed. Copy it, save it as index.html, and replace every [ ... ] with your own details. The responsive scaffolding — viewport meta tag, fluid container, media queries, and the menu-button pattern — is already in place, so the page is responsive before you write a line of layout:

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>[Your site name]</title>
  <meta name="description" content="[One or two sentences describing your site]" />
  <style>
    * { box-sizing: border-box; }
    body {
      margin: 0;
      font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
      line-height: 1.6;
    }
    img { max-width: 100%; height: auto; }

    .skip-link {
      position: absolute;
      left: -999px;
      top: 0;
      background: #111827;
      color: #ffffff;
      padding: 8px 14px;
      z-index: 10;
    }
    .skip-link:focus { left: 0; }

    .container {
      width: 100%;
      max-width: 68rem;
      margin: 0 auto;
      padding: 0 1.25rem;
    }

    header { background: [Header color]; color: #ffffff; }
    .header-inner {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-between;
      gap: 0.75rem 1rem;
      padding: 0.9rem 1.25rem;
    }
    .brand { margin: 0; font-size: 1.25rem; font-weight: 700; }

    .nav-toggle {
      display: inline-flex;
      align-items: center;
      gap: 0.5rem;
      border: 0;
      border-radius: 6px;
      padding: 0.5rem 0.75rem;
      font: inherit;
      color: #ffffff;
      background: [Button color];
      cursor: pointer;
    }

    nav { display: none; order: 10; width: 100%; }
    nav.open { display: block; }
    nav ul { list-style: none; margin: 0; padding: 0; }
    nav a { display: block; padding: 0.6rem 0; color: inherit; text-decoration: none; }

    section { padding: 3rem 0; }
    h1 { font-size: clamp(2rem, 5vw, 3.25rem); line-height: 1.1; }

    footer { background: [Footer color]; color: #ffffff; padding: 2rem 0; }

    @media (min-width: 40rem) {
      .nav-toggle { display: none; }
      nav, nav.open { display: block; order: 0; width: auto; }
      nav ul { display: flex; gap: 1.5rem; }
      nav a { padding: 0; }
    }
  </style>
  <noscript>
    <style>
      nav { display: block; }
      .nav-toggle { display: none; }
    </style>
  </noscript>
</head>
<body>
  <a class="skip-link" href="#main">Skip to main content</a>

  <header>
    <div class="container header-inner">
      <p class="brand">[Your site name]</p>
      <button class="nav-toggle" id="nav-toggle" type="button" aria-expanded="false" aria-controls="nav-menu">
        <span aria-hidden="true">&#9776;</span> Menu
      </button>
      <nav id="nav-menu" aria-label="Primary">
        <ul>
          <li><a href="#[section-1]">[Link 1]</a></li>
          <li><a href="#[section-2]">[Link 2]</a></li>
          <li><a href="#[section-3]">[Link 3]</a></li>
        </ul>
      </nav>
    </div>
  </header>

  <main id="main">
    <section>
      <div class="container">
        <h1>[Your headline]</h1>
        <p>[A sentence that tells visitors what you offer]</p>
      </div>
    </section>
    <!-- Add more sections for your content -->
  </main>

  <footer>
    <div class="container">
      <p>&copy; 2026 [Your site name]. All rights reserved.</p>
    </div>
  </footer>

  <script>
    const toggle = document.getElementById("nav-toggle");
    const menu = document.getElementById("nav-menu");
    toggle.addEventListener("click", () => {
      const open = menu.classList.toggle("open");
      toggle.setAttribute("aria-expanded", String(open));
    });
  </script>
</body>
</html>

Responsive website checklist

Run through this before you publish any page that should work on a phone:

markdown
# Responsive website checklist

## The viewport
- [ ] <meta name="viewport" content="width=device-width, initial-scale=1" /> is in the head
- [ ] Zoom is not disabled (no user-scalable=no or maximum-scale=1)
- [ ] The page has a unique <title> and a meta description

## Layout
- [ ] Written mobile-first: base styles are a single column
- [ ] Containers use max-width with auto margins, not fixed pixel widths
- [ ] Grids and flexbox use relative units (fr, %, rem)
- [ ] The page does not scroll sideways at any width

## Media queries
- [ ] Breakpoints use rem (relative) units, not device sizes
- [ ] Each breakpoint is triggered by the content, not by one phone
- [ ] The navigation collapses to a menu button on small screens

## Media and type
- [ ] Images and video use max-width: 100%; height: auto
- [ ] Font sizes scale (rem, clamp(), or media queries)
- [ ] Buttons and links are large enough to tap with a finger

## Test
- [ ] Checked at a phone width, a tablet width, and a desktop width
- [ ] Checked in portrait and landscape on a real phone
- [ ] All links, the menu, and the images work at every size

FAQ

Frequently asked questions

What is a responsive website example?
A responsive website example is a complete page you can copy and open that changes its layout to suit the screen viewing it. The example on this page is a single index.html for a fictional landscaping company that uses the viewport meta tag, a fluid grid, media queries, and a mobile navigation button.
What makes a website responsive?
Three things together: a viewport meta tag so phones render the page at their real width, a fluid layout built from relative units so columns and images grow and shrink, and media queries that switch the layout at chosen widths. Fluid typography and fluid images are the modern companions to those three.
How do I run this responsive website example?
Copy the code, save it as a file named index.html, and open that file in a browser. Then drag the window edge narrower and wider, or use the device toolbar in the browser's developer tools, to watch the layout reflow at the 40rem and 62rem breakpoints.
What is a media query?
A media query is a CSS rule that applies styles only while a condition is true, for example @media (min-width: 40rem). The widths where the layout changes are called breakpoints, and in the example the queries switch the navigation, the hero, and the footer at 40rem and 62rem.
Why do I need the viewport meta tag?
Mobile browsers assume a desktop-sized viewport (often 980px) and zoom the page out unless told otherwise. The viewport meta tag with width=device-width overrides that default, so the page renders at the phone's real width and your media queries trigger at the right sizes.
What breakpoints should I use?
Choose breakpoints where your content starts to look bad, not the sizes of particular phones, and write them in rem rather than px so they scale with the visitor's font size. This example uses 40rem and 62rem, and it needs no more because the fluid card grid reflows on its own.
Do I need JavaScript to make a responsive website?
No. The layout itself is plain HTML and CSS. The one thing that commonly needs a few lines of JavaScript is the mobile menu button, which toggles a class to show the navigation; the example includes that small script and a no-JavaScript fallback.
What is the difference between responsive and adaptive design?
Responsive design uses one fluid layout that reflows at breakpoints and serves the same HTML to everyone. Adaptive design detects the device and serves one of several fixed layouts. Responsive is the usual default today; the comparison table on this page spells out both.

What to do next

A single responsive page is one piece of a site. To build that page in the first place, the HTML website example shows the complete one-file version, and the static website example turns a folder of pages into a small site. The website structure examples page shows how pages and navigation fit together, and the website wireframe example shows how to sketch a layout before writing any code. For the surrounding concepts, browse the website basics library or start from the code examples hub.

Examples