10 CSS Sidebar Navigation 02 / 10

Responsive Sidebar Toggle with HTML and CSS

Warm editorial / print magazine theme (Fraunces + Newsreader, paper texture, drop caps).

Best foreditorial sites, literary magazines, long-form blogs, documentation that prizes a considered print aesthetic.

Pure CSS MIT licensed
Live Demo Open in tab
Open in playground

The code

<section class="sn-rsp" aria-label="Responsive sidebar toggle demo">
  <input type="checkbox" id="sn-rsp-nav" class="toggle" aria-label="Toggle navigation">
  <aside class="sidebar" aria-label="Magazine sections">
    <div class="head">
      <div class="kicker">Issue No. 47</div>
      <h2>The Margin</h2>
    </div>
    <nav class="nav" aria-label="Sections">
      <a class="item active" href="#"><span class="num">01</span>Featured Essay</a>
      <a class="item" href="#"><span class="num">02</span>Culture</a>
      <a class="item" href="#"><span class="num">03</span>Long Reads</a>
      <a class="item" href="#"><span class="num">04</span>Interviews</a>
      <div class="rule" aria-hidden="true"></div>
      <a class="item" href="#"><span class="num">05</span>Fiction</a>
      <a class="item" href="#"><span class="num">06</span>Poetry</a>
      <a class="item" href="#"><span class="num">07</span>Archive</a>
    </nav>
    <div class="foot">Saved for later — 4 stories</div>
  </aside>
  <label for="sn-rsp-nav" class="overlay" aria-hidden="true"></label>

  <div class="content">
    <div class="topbar">
      <label for="sn-rsp-nav" class="menu-btn" aria-label="Open navigation">
        <svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M4 6h16M4 12h16M4 18h16" stroke-width="2" stroke-linecap="round"/></svg>
      </label>
      <h1>Featured Essay</h1>
    </div>
    <article class="article">
      <p class="lead">On a responsive layout, the sidebar slides away on small screens and reappears with a tap of the menu — no JavaScript involved.</p>
      <p>This demonstration uses the classic checkbox toggle to drive a fully responsive off-canvas navigation. On wide screens the menu sits permanently to the left as a reading index. Resize the window below the breakpoint and the rail tucks itself off-canvas, summoned by the hamburger button and dismissed by tapping the dimmed overlay.</p>
      <p>Everything is hand-set in CSS: the transitions, the overlay, the breakpoint behaviour. The result is a warm, print-inspired interface that feels considered rather than templated.</p>
    </article>
  </div>
</section>
/* ─── 02 Responsive Sidebar Toggle — editorial magazine ──────── */
@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,[email protected],400;9..144,600;9..144,900&family=Newsreader:ital@0;1&display=swap');

.sn-rsp {
  --sn-rsp-paper: #f4ece0;
  --sn-rsp-ink: #2b211a;
  --sn-rsp-rust: #bb4430;
  --sn-rsp-olive: #7d8471;
  --sn-rsp-line: #d9cbb6;
  --sn-rsp-panel: #fbf6ee;

  position: relative;
  width: 100%;
  height: 600px;
  font-family: 'Newsreader', serif;
  background: var(--sn-rsp-paper);
  background-image: repeating-linear-gradient(0deg, rgba(43,33,26,.012) 0 2px, transparent 2px 4px);
  color: var(--sn-rsp-ink);
  display: flex;
  overflow: hidden;
  box-sizing: border-box;
}
.sn-rsp *, .sn-rsp *::before, .sn-rsp *::after { box-sizing: border-box; margin: 0; padding: 0; }

.sn-rsp .toggle { display: none; }
.sn-rsp .overlay { display: none; }

.sn-rsp .sidebar {
  width: 288px;
  background: var(--sn-rsp-panel);
  border-right: 2px solid var(--sn-rsp-ink);
  height: 100%;
  display: flex; flex-direction: column;
  transition: transform .4s cubic-bezier(.22,1,.36,1);
  z-index: 30;
  flex-shrink: 0;
}
.sn-rsp .head { padding: 2rem 1.8rem 1.4rem; border-bottom: 1px solid var(--sn-rsp-line); }
.sn-rsp .kicker { font-family: 'Fraunces'; font-weight: 600; font-size: .7rem; letter-spacing: .32em;
  text-transform: uppercase; color: var(--sn-rsp-rust); }
.sn-rsp .head h2 { font-family: 'Fraunces'; font-weight: 900; font-size: 1.9rem; line-height: 1; margin-top: .4rem; font-style: italic; }

.sn-rsp .nav { padding: 1.4rem 1rem; flex: 1; overflow-y: auto; }
.sn-rsp .item {
  display: flex; align-items: baseline; gap: .9rem;
  padding: .7rem 1rem; text-decoration: none; color: var(--sn-rsp-ink);
  font-size: 1.12rem; border-radius: 2px; position: relative; transition: .2s;
}
.sn-rsp .item .num { font-family: 'Fraunces'; font-weight: 600; font-size: .78rem; color: var(--sn-rsp-olive); min-width: 22px; }
.sn-rsp .item:hover { background: var(--sn-rsp-paper); padding-left: 1.35rem; }
.sn-rsp .item.active { color: var(--sn-rsp-rust); font-style: italic; font-weight: 600; }
.sn-rsp .item.active .num { color: var(--sn-rsp-rust); }
.sn-rsp .rule { height: 1px; background: var(--sn-rsp-line); margin: 1rem 1rem; }

.sn-rsp .foot { padding: 1.4rem 1.8rem; border-top: 2px solid var(--sn-rsp-ink); font-family: 'Fraunces'; font-size: .78rem; color: var(--sn-rsp-olive); }

.sn-rsp .content { flex: 1; display: flex; flex-direction: column; min-width: 0; overflow-y: auto; }
.sn-rsp .topbar {
  display: flex; align-items: center; gap: 1rem;
  padding: 1.2rem 2rem; border-bottom: 1px solid var(--sn-rsp-line);
  position: sticky; top: 0; background: var(--sn-rsp-paper); z-index: 10;
}
.sn-rsp .menu-btn {
  cursor: pointer; border: 1.5px solid var(--sn-rsp-ink); border-radius: 3px;
  padding: .45rem .55rem; display: none; background: none;
}
.sn-rsp .menu-btn svg { width: 20px; height: 20px; display: block; stroke: var(--sn-rsp-ink); }
.sn-rsp .topbar h1 { font-family: 'Fraunces'; font-weight: 900; font-size: 1.3rem; }
.sn-rsp .article { padding: 3rem; max-width: 680px; }
.sn-rsp .article .lead { font-family: 'Fraunces'; font-style: italic; font-weight: 400;
  font-size: 1.7rem; line-height: 1.4; margin-bottom: 1.6rem; }
.sn-rsp .article p { font-size: 1.12rem; line-height: 1.85; margin-bottom: 1.2rem; color: #3a2e25; }
.sn-rsp .article p:first-of-type::first-letter { float: left; font-family: 'Fraunces'; font-weight: 900;
  font-size: 3.4rem; line-height: .8; padding: .1rem .5rem .1rem 0; color: var(--sn-rsp-rust); }

@media (max-width: 860px) {
  .sn-rsp .sidebar { position: absolute; transform: translateX(-100%); box-shadow: 6px 0 40px rgba(0,0,0,.15); }
  .sn-rsp .toggle:checked ~ .sidebar { transform: translateX(0); }
  .sn-rsp .toggle:checked ~ .overlay { display: block; position: absolute; inset: 0; background: rgba(43,33,26,.4); z-index: 20; }
  .sn-rsp .menu-btn { display: block; }
}

@media (prefers-reduced-motion: reduce) {
  .sn-rsp .sidebar { transition: none; }
}

Search CodeFronts

Loading…