Pattern catalog · 5 of 5 loaded
v1.0Spring 2026Internal reference
Web Build Templates
Pattern Reference

Navigation library

5 navigation patterns
v1.0 · Spring 2026
Live

Five distinct nav patterns — from the side rail to the bottom-pinned dock. The nav signals what kind of site this is before the visitor reads a word.

How to use this: Pick based on site shape. 6+ sections one click away → side rail. Power-user tool → command palette. Editorial / reading-first → drawer or editorial top. Modern SaaS → bottom dock. The nav structure itself is a content choice.

Most marketing sites overuse the horizontal top nav. For 4 or fewer items, that's fine. For more, almost any of the patterns here works better.

01

Side Rail

Persistent

Vertical nav rail on the left, persistent. Logo top, links middle, account bottom. For docs, dashboards, content sites with deep IA.

Source HTML
<!doctype html><html><head><meta charset="utf-8"><link href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600&family=Geist+Mono:wght@400&display=swap" rel="stylesheet">
<style>*{box-sizing:border-box;margin:0;padding:0}body{font-family:'Geist',sans-serif;background:#fafafa;color:#0a0a0a;line-height:1.5;display:flex;min-height:100vh}
.rail{width:240px;background:#fff;border-right:1px solid #e5e5e5;padding:18px 14px;display:flex;flex-direction:column;gap:18px;flex-shrink:0;height:100vh;position:sticky;top:0}
.brand{padding:8px 10px;display:flex;align-items:center;gap:10px;font-weight:600;font-size:15px}
.brand .dt{width:24px;height:24px;background:linear-gradient(135deg,#7e3aff,#ff3a8c);border-radius:6px}
.search{padding:9px 12px;border:1px solid #e5e5e5;border-radius:8px;display:flex;align-items:center;gap:8px;font-size:13px;color:#999;background:#fafafa;cursor:pointer}
.search .kbd{margin-left:auto;padding:2px 6px;background:#fff;border:1px solid #e5e5e5;border-radius:4px;font-family:'Geist Mono',monospace;font-size:11px}
.sec{display:flex;flex-direction:column;gap:2px}
.sec h4{font-size:11px;color:#999;letter-spacing:.06em;text-transform:uppercase;font-weight:500;padding:6px 10px;margin-top:6px}
.lk{padding:8px 10px;display:flex;align-items:center;gap:10px;font-size:13px;color:#444;text-decoration:none;border-radius:6px;font-weight:500}
.lk:hover{background:#f5f5f5;color:#0a0a0a}
.lk.ac{background:#0a0a0a;color:#fff}
.lk .ic{width:16px;text-align:center;font-size:12px;color:#aaa}
.lk.ac .ic{color:#fff}
.lk .badge{margin-left:auto;font-family:'Geist Mono',monospace;font-size:10px;color:#999;padding:1px 6px;background:#f0f0f0;border-radius:4px}
.lk.ac .badge{background:rgba(255,255,255,.15);color:#fff}
.acc{margin-top:auto;padding:10px;border-top:1px solid #f0f0f0;display:flex;align-items:center;gap:10px;cursor:pointer}
.av{width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,#5eead4,#3a5fff);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:600;font-size:13px}
.acc .nm{font-size:13px;font-weight:500}
.acc .nm span{display:block;font-size:11px;color:#999;font-weight:400}
.body{flex:1;padding:36px 48px;display:flex;flex-direction:column;gap:18px}
.bc{font-family:'Geist Mono',monospace;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:#999}
.h{font-size:32px;font-weight:600;letter-spacing:-.02em}
.body p{font-size:15px;color:#666;max-width:60ch;line-height:1.6}
.tip{padding:14px 18px;background:#f0fdfa;border-left:3px solid #5eead4;color:#0a3a35;font-size:13px;border-radius:0 8px 8px 0;max-width:50ch}
@media(max-width:780px){.rail{width:60px;padding:14px 8px}.lk span:not(.kbd):not(.ic):not(.badge),.acc .nm,.brand span,.sec h4,.search>span{display:none}.body{padding:24px}}</style></head><body>
<aside class="rail">
<div class="brand"><div class="dt"></div><span>Lumen</span></div>
<div class="search">⌘ <span>Search…</span><span class="kbd">⌘K</span></div>
<div class="sec">
<a class="lk ac" href="#"><span class="ic">▢</span><span>Home</span></a>
<a class="lk" href="#"><span class="ic">⚡</span><span>Models</span><span class="badge">14</span></a>
<a class="lk" href="#"><span class="ic">⌥</span><span>API</span></a>
<a class="lk" href="#"><span class="ic">⊟</span><span>Logs</span><span class="badge">2</span></a>
</div>
<div class="sec"><h4>Workspace</h4>
<a class="lk" href="#"><span class="ic">●</span><span>Team</span></a>
<a class="lk" href="#"><span class="ic">$</span><span>Billing</span></a>
<a class="lk" href="#"><span class="ic">⚙</span><span>Settings</span></a>
</div>
<div class="sec"><h4>Resources</h4>
<a class="lk" href="#"><span class="ic">⌘</span><span>Docs</span></a>
<a class="lk" href="#"><span class="ic">↗</span><span>Status</span></a>
</div>
<div class="acc"><div class="av">PM</div><div class="nm">Priya M.<span>cumulus.ai</span></div></div>
</aside>
<main class="body"><div class="bc">Workspace · cumulus / production</div><h1 class="h">Welcome back, Priya.</h1><p>This is a side-rail nav layout — the rail stays visible across every page, supports nested sections, search, and account at the bottom. Common in dashboards, docs, and admin tools.</p><div class="tip">💡 Use this when you have 6+ top-level sections that all need to be one click away. For 4 or fewer sections, a horizontal nav is usually better.</div></main>
</body></html>
02

Command Palette

Power-user

Minimal top bar; ⌘K opens a search palette that's the actual nav. For power-user tools, devs, anywhere the fastest path is keyboard.

Source HTML
<!doctype html><html><head><meta charset="utf-8"><link href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>*{box-sizing:border-box;margin:0;padding:0}body{font-family:'Geist',sans-serif;background:#0a0e0f;color:#e8eaea;line-height:1.5;min-height:100vh;position:relative}
.bar{padding:14px 24px;border-bottom:1px solid rgba(255,255,255,.08);display:flex;justify-content:space-between;align-items:center}
.brand{display:flex;align-items:center;gap:8px;font-weight:600;font-size:15px}
.brand .dt{width:20px;height:20px;background:linear-gradient(135deg,#5eead4,#3a5fff);border-radius:5px}
.bar-r{display:flex;align-items:center;gap:14px}
.cmd-trigger{padding:7px 14px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.1);border-radius:8px;display:flex;align-items:center;gap:14px;font-size:13px;color:#888;cursor:pointer;font-family:'Geist',sans-serif;min-width:280px}
.cmd-trigger .kbd{margin-left:auto;padding:2px 6px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);border-radius:4px;font-family:'Geist Mono',monospace;font-size:11px;color:#bbb}
.av{width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,#5eead4,#3a5fff);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:600;font-size:13px}
.body{padding:48px 24px;text-align:center;display:flex;flex-direction:column;gap:14px;align-items:center}
.body h1{font-size:32px;font-weight:600;letter-spacing:-.02em}
.body p{font-size:14px;color:#888;max-width:48ch}
.modal{position:absolute;top:120px;left:50%;transform:translateX(-50%);width:560px;max-width:calc(100vw - 40px);background:rgba(15,20,22,.98);backdrop-filter:blur(24px);border:1px solid rgba(255,255,255,.12);border-radius:14px;box-shadow:0 32px 80px -16px rgba(0,0,0,.6),0 0 0 1px rgba(255,255,255,.04);overflow:hidden}
.input{padding:14px 18px;border-bottom:1px solid rgba(255,255,255,.08);display:flex;align-items:center;gap:10px}
.input::before{content:"⌘";color:#5eead4;font-size:16px}
.input input{flex:1;background:transparent;border:none;outline:none;color:#fff;font-family:inherit;font-size:15px}
.input input::placeholder{color:#555}
.input .esc{padding:2px 8px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);border-radius:4px;font-family:'Geist Mono',monospace;font-size:11px;color:#bbb}
.results{padding:8px;max-height:380px;overflow:auto}
.grp{padding:8px 6px 4px}
.grp h5{font-family:'Geist Mono',monospace;font-size:10px;color:#666;letter-spacing:.1em;text-transform:uppercase;padding:0 8px 4px}
.r{padding:9px 12px;display:flex;align-items:center;gap:12px;border-radius:6px;cursor:pointer}
.r:hover,.r.ac{background:rgba(94,234,212,.08)}
.r.ac{box-shadow:inset 0 0 0 1px rgba(94,234,212,.2)}
.r .ic{width:24px;height:24px;background:rgba(255,255,255,.06);border-radius:5px;display:flex;align-items:center;justify-content:center;font-size:11px;color:#5eead4}
.r .lbl{font-size:13px;color:#e8eaea;font-weight:500;flex:1}
.r .lbl span{display:block;font-size:11px;color:#777;font-weight:400;margin-top:1px}
.r .sh{font-family:'Geist Mono',monospace;font-size:10px;color:#777;letter-spacing:.04em}
.foot{padding:8px 14px;border-top:1px solid rgba(255,255,255,.08);display:flex;justify-content:space-between;font-family:'Geist Mono',monospace;font-size:10px;color:#666;letter-spacing:.04em}
.foot span b{color:#aaa}
@media(max-width:680px){.cmd-trigger{min-width:auto}.cmd-trigger span:not(.kbd){display:none}.modal{top:90px}}</style></head><body>
<div class="bar"><div class="brand"><div class="dt"></div>Lumen</div><div class="bar-r"><div class="cmd-trigger">⌘ <span>Search or jump to…</span><span class="kbd">⌘K</span></div><div class="av">P</div></div></div>
<div class="body"><h1>The nav lives in ⌘K.</h1><p>One bar. One shortcut. Every page, action, doc, and setting one fuzzy match away.</p></div>
<div class="modal">
<div class="input"><input value="model" autofocus><span class="esc">esc</span></div>
<div class="results">
<div class="grp"><h5>Pages · 4 results</h5>
<div class="r ac"><div class="ic">⚡</div><div class="lbl">Models<span>Browse and select inference models</span></div><span class="sh">↵</span></div>
<div class="r"><div class="ic">⌥</div><div class="lbl">Model playground<span>Test models in browser</span></div><span class="sh">G+P</span></div>
<div class="r"><div class="ic">$</div><div class="lbl">Model pricing<span>Per-model rate card</span></div></div>
</div>
<div class="grp"><h5>Actions</h5>
<div class="r"><div class="ic">+</div><div class="lbl">Create new model deployment</div><span class="sh">⌘N</span></div>
<div class="r"><div class="ic">↗</div><div class="lbl">Switch to model: gpt-mini-7b</div></div>
</div>
<div class="grp"><h5>Docs</h5>
<div class="r"><div class="ic">⌘</div><div class="lbl">Models API reference<span>docs.lumen.ai/models</span></div></div>
</div>
</div>
<div class="foot"><span><b>↑↓</b> navigate · <b>↵</b> select · <b>⌘K</b> close</span><span>Lumen v0.4.2</span></div>
</div>
</body></html>
03

Drawer Only

Reductive

No visible nav at all — just a logo and a menu button. Whole nav lives in a full-screen drawer. For editorial sites, content brands prioritizing reading.

Source HTML
<!doctype html><html><head><meta charset="utf-8"><link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,600;1,9..144,400&family=Inter:wght@400;500&display=swap" rel="stylesheet">
<style>*{box-sizing:border-box;margin:0;padding:0}body{font-family:'Inter',sans-serif;background:#f4efe6;color:#1a1814;line-height:1.5;min-height:100vh;position:relative}
.bar{padding:24px 36px;display:flex;justify-content:space-between;align-items:center}
.brand{font-family:'Fraunces',serif;font-weight:600;font-size:24px;letter-spacing:-.015em}
.brand em{font-style:italic;color:#a4341e}
.menu-btn{padding:10px 18px;background:transparent;border:1.5px solid #1a1814;color:#1a1814;font-family:inherit;font-weight:500;font-size:13px;border-radius:999px;cursor:pointer;display:flex;align-items:center;gap:10px;letter-spacing:.04em}
.menu-btn:hover{background:#1a1814;color:#f4efe6}
.menu-btn .ln{display:flex;flex-direction:column;gap:3px}
.menu-btn .ln span{display:block;width:14px;height:1.5px;background:currentColor}
.body{padding:48px 36px;text-align:center;display:flex;flex-direction:column;gap:14px;align-items:center}
.body h1{font-family:'Fraunces',serif;font-weight:400;font-size:36px;letter-spacing:-.02em}
.body p{font-size:15px;color:#5a5040;max-width:48ch}
.drawer{position:fixed;inset:0;background:#1a1814;color:#f4efe6;z-index:50;padding:48px 64px;display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:center}
.dr-close{position:absolute;top:24px;right:36px;background:transparent;border:1.5px solid #f4efe6;color:#f4efe6;padding:10px 18px;border-radius:999px;font-family:inherit;font-weight:500;font-size:13px;cursor:pointer;letter-spacing:.04em}
.dr-close:hover{background:#f4efe6;color:#1a1814}
.dr-l ul{list-style:none}
.dr-l li{font-family:'Fraunces',serif;font-weight:400;font-size:60px;letter-spacing:-.025em;line-height:1.0;padding:8px 0;display:flex;align-items:baseline;gap:18px}
.dr-l li:hover{color:#a4341e}
.dr-l li:hover em{color:#a4341e}
.dr-l li em{font-style:italic;color:rgba(244,239,230,.4);font-weight:400;font-size:14px;letter-spacing:.06em;text-transform:uppercase;font-family:'Inter',sans-serif}
.dr-r{display:flex;flex-direction:column;gap:36px}
.dr-r .ft{padding:24px 0;border-top:1px solid rgba(244,239,230,.2);border-bottom:1px solid rgba(244,239,230,.2);display:flex;flex-direction:column;gap:14px}
.dr-r .ft .item{display:flex;justify-content:space-between;font-size:14px}
.dr-r .ft .item span{color:rgba(244,239,230,.5);font-size:11px;letter-spacing:.1em;text-transform:uppercase}
.dr-r .ft .item b{font-family:'Fraunces',serif;font-weight:400;font-size:18px;font-style:italic}
.dr-r p{font-family:'Fraunces',serif;font-style:italic;font-size:15px;color:rgba(244,239,230,.7);line-height:1.55}
.dr-r .scl{display:flex;gap:14px;font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:rgba(244,239,230,.5)}
.dr-r .scl a{color:#f4efe6;text-decoration:none;border-bottom:1px solid #a4341e}
@media(max-width:880px){.drawer{grid-template-columns:1fr;padding:80px 24px 32px;gap:24px;overflow:auto}.dr-l li{font-size:36px}}</style></head><body>
<div class="bar"><div class="brand">Hollow <em>&amp; Co.</em></div><button class="menu-btn"><span class="ln"><span></span><span></span><span></span></span>Menu</button></div>
<div class="body"><h1>Reading mode.</h1><p>No nav, no menu bar, no sticky header. Just the work. Press the menu button when you want to go somewhere.</p></div>
<div class="drawer">
<button class="dr-close">Close ✕</button>
<div class="dr-l"><ul>
<li>Catalog <em>01</em></li>
<li><em style="color:#a4341e">Workshop</em> <em>02</em></li>
<li>Journal <em>03</em></li>
<li>About <em>04</em></li>
<li>Contact <em>05</em></li>
</ul></div>
<div class="dr-r">
<div class="ft">
<div class="item"><span>Visit</span><b>Tuesdays only</b></div>
<div class="item"><span>Email</span><b>dean@hollowco.com</b></div>
<div class="item"><span>Phone</span><b>(207) 555 — 1842</b></div>
</div>
<p>"Made one piece at a time, in our shop in Camden, Maine. Sold here, and almost nowhere else, on purpose."</p>
<div class="scl"><a>Instagram</a> · <a>Newsletter</a></div>
</div>
</div>
</body></html>
04

Bottom Pinned

Modern

Floating bottom-pinned nav island. Modern, app-like, distinctive. For SaaS, AI products, anywhere wanting a contemporary feel.

Source HTML
<!doctype html><html><head><meta charset="utf-8"><link href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600&display=swap" rel="stylesheet">
<style>*{box-sizing:border-box;margin:0;padding:0}body{font-family:'Geist',sans-serif;background:#0a0512;color:#fff;line-height:1.5;min-height:100vh;position:relative;overflow:hidden}
.bg{position:absolute;inset:0;background:radial-gradient(circle at 20% 30%,#7e3aff 0%,transparent 35%),radial-gradient(circle at 80% 70%,#ff3a8c 0%,transparent 40%);filter:blur(80px);opacity:.4}
.body{padding:64px 36px;text-align:center;position:relative;z-index:2;display:flex;flex-direction:column;gap:14px;align-items:center;max-width:680px;margin:0 auto}
.k{font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:#5eead4;background:rgba(94,234,212,.1);border:1px solid rgba(94,234,212,.3);padding:5px 12px;border-radius:999px;display:inline-flex;align-items:center;gap:8px}
.k::before{content:"";width:6px;height:6px;background:#5eead4;border-radius:50%}
.h{font-size:48px;font-weight:600;letter-spacing:-.025em;line-height:1.05}
.h em{font-style:italic;color:#5eead4}
.p{font-size:15px;color:rgba(255,255,255,.7);max-width:48ch;line-height:1.6}
.dock{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);background:rgba(15,10,30,.85);backdrop-filter:blur(24px) saturate(180%);border:1px solid rgba(255,255,255,.12);border-radius:999px;padding:6px;display:flex;align-items:center;gap:4px;box-shadow:0 24px 64px -12px rgba(0,0,0,.6),inset 0 0 0 1px rgba(255,255,255,.04);z-index:10}
.dl{padding:9px 16px;display:flex;align-items:center;gap:8px;color:rgba(255,255,255,.7);text-decoration:none;font-size:13px;font-weight:500;border-radius:999px;transition:all .2s;font-family:inherit;background:transparent;border:none;cursor:pointer}
.dl:hover{color:#fff;background:rgba(255,255,255,.06)}
.dl.ac{background:linear-gradient(135deg,#7e3aff,#ff3a8c);color:#fff;box-shadow:0 4px 16px rgba(126,58,255,.4)}
.dl .ic{font-size:14px}
.dl .badge{padding:1px 6px;background:rgba(255,255,255,.15);border-radius:999px;font-size:10px;font-weight:600}
.dl.ac .badge{background:rgba(255,255,255,.25)}
.div{width:1px;height:18px;background:rgba(255,255,255,.1);margin:0 4px}
.dl.cta{background:#fff;color:#0a0512;font-weight:600;padding:9px 18px}
.dl.cta:hover{background:#5eead4}
@media(max-width:680px){.dock{flex-wrap:wrap;justify-content:center;width:calc(100% - 32px);max-width:480px}.h{font-size:32px}.dl span:not(.ic):not(.badge){display:none}.dl.cta span{display:inline}}</style></head><body><div class="bg"></div>
<div class="body"><div class="k">v0.4.2 · Live now</div><h1 class="h">Inference, <em>finally fast</em>.</h1><p class="p">Run your models on the cheapest, fastest infrastructure available. Pay per token, scale to zero, ship today.</p></div>
<nav class="dock">
<button class="dl ac"><span class="ic">▢</span><span>Home</span></button>
<button class="dl"><span class="ic">⚡</span><span>Models</span><span class="badge">14</span></button>
<button class="dl"><span class="ic">$</span><span>Pricing</span></button>
<button class="dl"><span class="ic">⌘</span><span>Docs</span></button>
<div class="div"></div>
<button class="dl"><span>Log in</span></button>
<button class="dl cta"><span>Get started →</span></button>
</nav>
</body></html>
05

Editorial Top

Classic

Magazine-style top nav: serif logo, flat link list, no decorations. Distinctive type does the work. For publications, content brands, considered companies.

Source HTML
<!doctype html><html><head><meta charset="utf-8"><link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,600;0,9..144,800;1,9..144,400&family=Inter:wght@400;500&display=swap" rel="stylesheet">
<style>*{box-sizing:border-box;margin:0;padding:0}body{font-family:'Inter',sans-serif;background:#fcfaf5;color:#1a1612;line-height:1.5;min-height:100vh}
.top-bar{padding:8px 36px;background:#1a1612;color:#fcfaf5;display:flex;justify-content:space-between;align-items:center;font-family:'Inter',sans-serif;font-size:11px;letter-spacing:.12em;text-transform:uppercase}
.top-bar .l{display:flex;gap:18px}
.top-bar .l a{color:#fcfaf5;text-decoration:none;opacity:.7}
.top-bar .l a:hover{opacity:1;color:#a4341e}
.top-bar .r{display:flex;gap:18px;align-items:center}
.top-bar .r .live{color:#a4341e;display:inline-flex;align-items:center;gap:6px}
.top-bar .r .live::before{content:"";width:6px;height:6px;background:#a4341e;border-radius:50%;animation:p 1.6s ease-in-out infinite}
@keyframes p{50%{opacity:.4}}
.mh{padding:32px 36px 14px;text-align:center;border-bottom:1px solid #d4cabb}
.brand{font-family:'Fraunces',serif;font-weight:800;font-size:64px;letter-spacing:-.04em;line-height:.9}
.brand em{font-style:italic;font-weight:400}
.tag{margin-top:10px;font-family:'Fraunces',serif;font-style:italic;font-size:14px;color:#7a6f5f}
.nav{padding:14px 36px;border-bottom:2px solid #1a1612;display:flex;justify-content:center;gap:32px;background:#fcfaf5;position:sticky;top:0;z-index:10}
.nav a{color:#1a1612;text-decoration:none;font-family:'Fraunces',serif;font-size:18px;font-weight:600;letter-spacing:-.005em;border-bottom:2px solid transparent;padding:6px 0}
.nav a:hover{color:#a4341e}
.nav a.ac{border-bottom-color:#a4341e;color:#a4341e}
.nav a em{font-style:italic;font-weight:400}
.body{padding:48px 36px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:14px;max-width:680px;margin:0 auto}
.body h1{font-family:'Fraunces',serif;font-weight:400;font-size:32px;letter-spacing:-.02em;font-style:italic}
.body p{font-size:15px;color:#5a5040;max-width:48ch}
@media(max-width:780px){.brand{font-size:36px}.nav{gap:16px;overflow-x:auto;justify-content:flex-start;padding:14px 24px}.top-bar{display:none}.nav a{font-size:14px;flex-shrink:0}}</style></head><body>
<div class="top-bar"><div class="l"><a>Subscribe</a><a>Newsletter</a><a>Contact</a></div><div class="r"><span>Vol XII · No 47</span><span class="live">Live · publishing now</span></div></div>
<div class="mh"><div class="brand">Th<em>e</em> Periphery</div><div class="tag">"For people who'd rather think than scroll." — est. 2014</div></div>
<nav class="nav">
<a href="#">Reported</a>
<a href="#" class="ac">Essays</a>
<a href="#"><em>Interviews</em></a>
<a href="#">Photo</a>
<a href="#">Letters</a>
<a href="#" style="color:#a4341e">№ 47 →</a>
</nav>
<div class="body"><h1>An editorial nav, done with care.</h1><p>Big serif logotype, flat link list, magazine-style top bar. Distinctive type doing all the work — no icons, no badges, no SaaS dropdowns.</p></div>
</body></html>
Copied