RWD Responsive Sidebar Layout Template

Learn how to build a sidebar layout that places navigation beside the main content on desktop and stacks it above the content on smaller screens.

The Sidebar Layout Pattern

Dashboards, documentation sites, admin panels, and many blogs share a common shape: a narrow strip of navigation or filters running down one side, with the main content filling the rest of the width. On a desktop monitor that side-by-side arrangement is efficient because there is plenty of horizontal room. On a phone, forcing a 240px sidebar to squeeze next to content leaves almost nothing for either one, so the layout needs to change shape entirely at narrow widths, with the sidebar moving above or below the content instead of beside it.

Building It With Flexbox

Flexbox is a natural fit because a sidebar layout is really just two boxes in a row that need to become two boxes in a column. Make the outer wrapper display: flex. Give the sidebar a fixed width using flex: 0 0 240px, which means 'do not grow, do not shrink, start at 240px wide.' Give the content area flex: 1 1 auto so it stretches to absorb all remaining horizontal space. Then, inside a @media query at your chosen breakpoint, switch the wrapper to flex-direction: column. Because the sidebar appears first in the HTML, it will naturally render above the content once the direction flips to a column, with no reordering needed.

Example: Flexbox Sidebar Layout

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  * { box-sizing: border-box; }
  body { margin: 0; font-family: Arial, sans-serif; }
  .layout { display: flex; min-height: 100vh; }
  .sidebar {
    flex: 0 0 240px;
    background: #263238;
    color: #fff;
    padding: 20px;
  }
  .content {
    flex: 1 1 auto;
    padding: 20px;
    background: #fafafa;
  }

  @media (max-width: 700px) {
    .layout { flex-direction: column; }
    .sidebar { flex: 0 0 auto; }
  }
</style>
</head>
<body>
  <div class='layout'>
    <nav class='sidebar'>
      <h2>Menu</h2>
      <p>Home</p>
      <p>About</p>
      <p>Contact</p>
    </nav>
    <main class='content'>
      <h1>Main Content</h1>
      <p>This is the main content area beside the sidebar.</p>
    </main>
  </div>
</body>
</html>
  • flex: 0 0 240px keeps the sidebar's width fixed even if the content area has very little text.
  • flex: 1 1 auto lets the content claim every remaining pixel instead of leaving a gap.
  • Switching to flex-direction: column at the breakpoint is enough to stack both boxes, no width values need to change.
  • Resetting the sidebar to flex: 0 0 auto on mobile lets its height be determined by its own content instead of staying pinned to a fixed size meant for the desktop width.

Building It With Grid (Alternative)

CSS Grid offers a second way to build the same layout, and it becomes especially handy once you have more than two regions, like a header and footer alongside the sidebar and content. Define grid-template-columns: 240px 1fr for the two columns, and give each child a named grid-area so the markup order no longer dictates the visual order. At the mobile breakpoint, redefine grid-template-columns as a single 1fr column and redraw grid-template-areas as a stacked list of rows. This lets you freely reorder pieces at each breakpoint, for example putting the sidebar below the content on mobile even though it comes first in the HTML, which flexbox cannot do without extra order properties.

Example: Grid Sidebar Layout with Named Areas

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  * { box-sizing: border-box; }
  body { margin: 0; font-family: Arial, sans-serif; }
  .layout {
    display: grid;
    grid-template-columns: 240px 1fr;
    grid-template-areas: 'sidebar content';
    min-height: 100vh;
  }
  .sidebar { grid-area: sidebar; background: #37474f; color: #fff; padding: 20px; }
  .content { grid-area: content; padding: 20px; }

  @media (max-width: 700px) {
    .layout {
      grid-template-columns: 1fr;
      grid-template-areas:
        'sidebar'
        'content';
    }
  }
</style>
</head>
<body>
  <div class='layout'>
    <nav class='sidebar'>
      <h2>Menu</h2>
      <p>Home</p>
      <p>About</p>
    </nav>
    <main class='content'>
      <h1>Main Content</h1>
      <p>Grid areas let you reorder regions at each breakpoint without touching the HTML.</p>
    </main>
  </div>
</body>
</html>
FlexboxGrid
Simplest choice for exactly two regions (sidebar + content).Better once you add more regions, like a header or footer, that need independent placement.
Reordering visually requires the order property.Reordering is built in via grid-template-areas, so markup order can differ from visual order.
Note: Pick your breakpoint based on where the sidebar and content actually start feeling cramped, not on a specific device. Testing with real content, like a long navigation label or a wide table, often reveals that the layout needs to stack sooner than a generic 768px guess.

On mobile, consider whether the sidebar should always be visible above the content, as shown here, or whether it should collapse behind a toggle button instead. A short list of two or three links usually reads fine stacked above the content, while a long navigation menu often benefits from being hidden until the user taps to open it.

Exercise: RWD Templates

What should a developer verify before trusting a template labeled "responsive"?