Inklapbare zijbalk voor een klantportaal New
Sidebar for a client portal that collapses into a narrow icon rail. When collapsed the label appears as a tooltip next to the icon on hover and keyboard focus, so every link keeps a name. The button reports its state with aria-expanded, Ctrl+B also toggles it and the choice is remembered in localStorage (with try/catch). On a narrow screen it starts collapsed. For portals, dashboards and admin areas with five to ten main sections.
Overzicht
Openstaand: € 1.284,50 in 2 facturen. De eerstvolgende vervalt op 20 oktober.
How to use it
- Paste the HTML where the navigation & menus should appear.
- Add the CSS to your stylesheet. All classes are prefixed, so nothing clashes with your own styles.
- Add the JavaScript and call init() with the element that contains the HTML.
<!-- Inklapbare zijbalk voor een klantportaal · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="zbp">
<aside class="zbp__side" id="zbp-side">
<div class="zbp__top"><span class="zbp__logo" aria-hidden="true">W</span><span class="zbp__name">Woonzorg Delta</span>
<button class="zbp__tgl" type="button" aria-expanded="true" aria-controls="zbp-side" aria-label="Zijbalk inklappen"><svg viewBox="0 0 16 16" aria-hidden="true"><path d="M10 3L5 8l5 5"/></svg></button></div>
<nav class="zbp__nav" aria-label="Portaal">
<a class="zbp__a" href="#zbp-overzicht" aria-current="page"><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="4" y="4" width="7" height="7" rx="1"/><rect x="13" y="4" width="7" height="7" rx="1"/><rect x="4" y="13" width="7" height="7" rx="1"/><rect x="13" y="13" width="7" height="7" rx="1"/></svg><span class="zbp__lab">Overzicht</span></a>
<a class="zbp__a" href="#zbp-facturen"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 3h12v18l-3-2-3 2-3-2-3 2z"/><path d="M9 8h6M9 12h6"/></svg><span class="zbp__lab">Facturen</span><b class="zbp__badge">2</b></a>
<a class="zbp__a" href="#zbp-documenten"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7 3h7l5 5v13H7z"/><path d="M14 3v5h5"/></svg><span class="zbp__lab">Documenten</span></a>
<a class="zbp__a" href="#zbp-afspraken"><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M4 10h16M9 3v4M15 3v4"/></svg><span class="zbp__lab">Afspraken</span></a>
</nav>
</aside>
<main class="zbp__main">
<h3 class="zbp__h">Overzicht</h3>
<p class="zbp__t">Openstaand: € 1.284,50 in 2 facturen. De eerstvolgende vervalt op 20 oktober.</p>
</main>
</div>
</div>/* Inklapbare zijbalk voor een klantportaal · NedDev · eigen werk. */
.zbp{position:absolute;inset:0;display:flex;background:#f4f3f1;color:#0a0a0a;font-family:'Switzer',sans-serif;text-align:left}
.zbp *,.zbp *::before,.zbp *::after{box-sizing:border-box}
.zbp__side{position:relative;z-index:2;flex:none;width:204px;display:flex;flex-direction:column;gap:4px;padding:10px 8px;background:#0a0a0a;color:#fff;transition:width .24s cubic-bezier(.3,.7,.2,1)}
.zbp__top{position:relative;display:flex;align-items:center;gap:8px;height:36px;margin-bottom:6px;padding-left:4px}
.zbp__logo{flex:none;display:grid;place-items:center;width:28px;height:28px;border-radius:4px;background:#F5480F;color:#0a0a0a;font:700 15px/1 'Switzer',sans-serif}
.zbp__name{flex:1;min-width:0;font:600 14px/1.1 'Switzer',sans-serif;white-space:nowrap;overflow:hidden;transition:opacity .16s}
.zbp__tgl{flex:none;display:grid;place-items:center;width:28px;height:28px;margin:0;padding:0;border:1px solid rgba(255,255,255,.3);border-radius:4px;background:none;color:#fff;cursor:pointer}
.zbp__tgl:hover{border-color:#fff}
.zbp__tgl:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.zbp__tgl svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:transform .24s}
.zbp__nav{display:flex;flex-direction:column;gap:2px}
.zbp__a{position:relative;display:flex;align-items:center;gap:10px;height:34px;padding:0 9px;border-radius:4px;color:#d6d3cd;text-decoration:none;font:500 14px/1 'Switzer',sans-serif;outline:none}
.zbp__a svg{flex:none;width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.zbp__a:hover{background:rgba(255,255,255,.08);color:#fff}
.zbp__a[aria-current="page"]{background:#fff;color:#0a0a0a}
.zbp__a:focus-visible{box-shadow:inset 0 0 0 2px #F5480F}
.zbp__lab{white-space:nowrap;transition:opacity .16s}
.zbp__badge{margin-left:auto;min-width:20px;height:20px;padding:0 5px;border-radius:4px;background:#F5480F;color:#0a0a0a;font:700 12px/20px 'Switzer',sans-serif;text-align:center}
.zbp.is-mini .zbp__side{width:56px}
.zbp.is-mini .zbp__name{opacity:0;width:0;flex:0}
.zbp.is-mini .zbp__top{padding-left:6px}
.zbp.is-mini .zbp__logo{display:none}
.zbp.is-mini .zbp__tgl svg{transform:rotate(180deg)}
.zbp.is-mini .zbp__lab{position:absolute;left:calc(100% + 10px);top:50%;transform:translate(-4px,-50%);padding:6px 8px;border-radius:4px;background:#0a0a0a;color:#fff;font:500 13px/1 'Switzer',sans-serif;opacity:0;pointer-events:none;transition:opacity .14s,transform .14s}
.zbp.is-mini .zbp__a:hover .zbp__lab,.zbp.is-mini .zbp__a:focus-visible .zbp__lab{opacity:1;transform:translate(0,-50%)}
.zbp.is-mini .zbp__badge{position:absolute;top:2px;right:2px;min-width:16px;height:16px;padding:0 3px;font-size:12px;line-height:16px}
.zbp__main{flex:1;min-width:0;padding:18px 20px;overflow:auto}
.zbp__h{margin:0 0 6px;font:600 20px/1.15 'Switzer',sans-serif;letter-spacing:-.015em}
.zbp__t{margin:0;font:400 14px/1.45 'Switzer',sans-serif;color:#3a3733;max-width:32em}
@media (prefers-reduced-motion:reduce){.zbp__side,.zbp__tgl svg,.zbp__name,.zbp__lab,.zbp.is-mini .zbp__lab{transition:none}}// Inklapbare zijbalk voor een klantportaal · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.zbp');if(!w)return;
var tgl=w.querySelector('.zbp__tgl'),links=[].slice.call(w.querySelectorAll('.zbp__a')),h=w.querySelector('.zbp__h'),t=w.querySelector('.zbp__t'),KEY='zbp-ingeklapt';
var TXT={Overzicht:'Openstaand: \u20ac 1.284,50 in 2 facturen. De eerstvolgende vervalt op 20 oktober.',Facturen:'2 facturen staan open. Betalen kan met iDEAL of per overschrijving.',Documenten:'Je huurcontract en de laatste jaarafrekening staan klaar om te downloaden.',Afspraken:'Onderhoud cv-ketel op woensdag 22 oktober tussen 8:00 en 12:00.'};
function set(mini,save){w.classList.toggle('is-mini',mini);tgl.setAttribute('aria-expanded',mini?'false':'true');tgl.setAttribute('aria-label',mini?'Zijbalk uitklappen':'Zijbalk inklappen');
if(save){try{localStorage.setItem(KEY,mini?'1':'0');}catch(e){}}}
var saved=null;try{saved=localStorage.getItem(KEY);}catch(e){}
set(saved===null?w.clientWidth<380:saved==='1',false);
tgl.addEventListener('click',function(){set(!w.classList.contains('is-mini'),true);});
w.addEventListener('keydown',function(e){if((e.ctrlKey||e.metaKey)&&(e.key==='b'||e.key==='B')){e.preventDefault();set(!w.classList.contains('is-mini'),true);}});
links.forEach(function(a){a.addEventListener('click',function(e){e.preventDefault();links.forEach(function(o){o.removeAttribute('aria-current');});a.setAttribute('aria-current','page');var n=a.querySelector('.zbp__lab').textContent;h.textContent=n;t.textContent=TXT[n]||'';});});
}
init(document.querySelector('.jouw-container'));
More navigation & menus
Seen something you like?
Add it to your selection and send it over. We build your site around it, in your brand.
Get in touch →