Tabs met glijdende onderstreping New
Product tabs where the orange underline glides to the new tab and the content slides in the direction of your click. One View Transition for both line and panel (with types for direction); without support everything jumps instantly. Keyboard: arrows, Home and End. If the tabs are real pages: @view-transition { navigation: auto; } and the same view-transition-name on the line and the panel on every page.
Werkt samen met je huidige cv-ketel en neemt het grootste deel van de verwarming over.
Gemiddeld 60% minder gas in een tussenwoning uit de jaren zeventig. Installatie in één dag, de buitenunit hangt aan de gevel of staat op een tegel.
- Vermogen
- 4,0 kW
- Geluid op 3 m
- 38 dB(A)
- SCOP bij 35 °C
- 4,6
- Subsidie
- ISDE mogelijk
9"Monteurs waren om vier uur klaar en hebben alles netjes afgewerkt. Ons gasverbruik is bijna gehalveerd."
Karin, Apeldoorn · gemiddeld 8,6 uit 214 beoordelingen
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.
<!-- Tabs met glijdende onderstreping · NedDev · eigen werk. -->
<div class="jouw-container">
<!-- De streep is één element dat in de actieve tab wordt geplaatst; met view-transition-name: vtb-ind laat de browser hem glijden.
Tabs als losse pagina's (/product/specificaties): @view-transition { navigation: auto; } en op elke pagina de streep met
view-transition-name: vtb-ind en het paneel met vtb-panel. Richting via pagereveal + e.viewTransition.types.add('vtb-rechts').
Reduced motion: @media (prefers-reduced-motion: reduce) { ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; } } -->
<div class="vtb">
<div class="vtb__head"><span class="vtb__kick">Hybride warmtepomp 4 kW</span><span class="vtb__price">€ 4.295 incl. montage</span></div>
<div class="vtb__list" role="tablist" aria-label="Productinformatie">
<button class="vtb__tab" role="tab" type="button" id="vtb-t1" aria-controls="vtb-p1" aria-selected="true">Overzicht<span class="vtb__ind" aria-hidden="true"></span></button>
<button class="vtb__tab" role="tab" type="button" id="vtb-t2" aria-controls="vtb-p2" aria-selected="false" tabindex="-1">Specificaties</button>
<button class="vtb__tab" role="tab" type="button" id="vtb-t3" aria-controls="vtb-p3" aria-selected="false" tabindex="-1">Reviews <span class="vtb__score">8,6</span></button>
</div>
<div class="vtb__panels">
<div class="vtb__panel" role="tabpanel" id="vtb-p1" aria-labelledby="vtb-t1" tabindex="0">
<p class="vtb__lead">Werkt samen met je huidige cv-ketel en neemt het grootste deel van de verwarming over.</p>
<p class="vtb__p">Gemiddeld 60% minder gas in een tussenwoning uit de jaren zeventig. Installatie in één dag, de buitenunit hangt aan de gevel of staat op een tegel.</p>
</div>
<div class="vtb__panel" role="tabpanel" id="vtb-p2" aria-labelledby="vtb-t2" tabindex="0" hidden>
<dl class="vtb__dl"><div><dt>Vermogen</dt><dd>4,0 kW</dd></div><div><dt>Geluid op 3 m</dt><dd>38 dB(A)</dd></div><div><dt>SCOP bij 35 °C</dt><dd>4,6</dd></div><div><dt>Subsidie</dt><dd>ISDE mogelijk</dd></div></dl>
</div>
<div class="vtb__panel" role="tabpanel" id="vtb-p3" aria-labelledby="vtb-t3" tabindex="0" hidden>
<p class="vtb__rev"><b class="vtb__cijfer">9</b>"Monteurs waren om vier uur klaar en hebben alles netjes afgewerkt. Ons gasverbruik is bijna gehalveerd."</p>
<p class="vtb__who">Karin, Apeldoorn · gemiddeld 8,6 uit 214 beoordelingen</p>
</div>
</div>
</div>
</div>/* Tabs met glijdende onderstreping · NedDev · eigen werk. */
.vtb{position:absolute;inset:0;display:flex;flex-direction:column;padding:13px 16px 12px;background:#fff;color:#0a0a0a;font-family:'Switzer',system-ui,sans-serif;overflow:hidden}
.vtb__head{display:flex;justify-content:space-between;align-items:baseline;gap:8px;margin-bottom:8px}
.vtb__kick{font-weight:700;font-size:14px}
.vtb__price{font:500 10.5px 'JetBrains Mono',monospace;color:rgba(10,10,10,.6);white-space:nowrap}
.vtb__list{display:flex;gap:4px;border-bottom:1px solid rgba(10,10,10,.12)}
.vtb__tab{all:unset;box-sizing:border-box;position:relative;font-size:12.5px;font-weight:500;padding:8px 9px 9px;color:rgba(10,10,10,.6);cursor:pointer;white-space:nowrap;transition:color .15s}
.vtb__tab:hover{color:#0a0a0a}
.vtb__tab[aria-selected="true"]{color:#0a0a0a;font-weight:600}
.vtb__tab:focus-visible{outline:2px solid #F5480F;outline-offset:-2px;border-radius:4px}
.vtb__ind{position:absolute;left:6px;right:6px;bottom:-1px;height:2px;background:#F5480F;border-radius:2px}
.vtb__score{font:600 10px 'JetBrains Mono',monospace;background:#0a0a0a;color:#fff;padding:1px 5px;border-radius:3px;margin-left:3px}
.vtb__panels{flex:1;min-height:0;position:relative;padding-top:12px}
.vtb__panel{outline:none}
.vtb__panel:focus-visible{outline:2px solid #F5480F;outline-offset:2px;border-radius:2px}
.vtb__lead{margin:0 0 7px;font-size:14px;line-height:1.35;font-weight:600;max-width:30em}
.vtb__p{margin:0;font-size:12.5px;line-height:1.5;color:rgba(10,10,10,.7)}
.vtb__dl{margin:0;display:grid;grid-template-columns:1fr 1fr;gap:0 16px}
.vtb__dl div{display:flex;justify-content:space-between;gap:8px;padding:6px 0;border-bottom:1px solid rgba(10,10,10,.09);font-size:12px}
.vtb__dl dt{margin:0;color:rgba(10,10,10,.6)}.vtb__dl dd{margin:0;font-family:'JetBrains Mono',monospace;font-size:11.5px;white-space:nowrap}
.vtb__rev{margin:0 0 8px;font-size:13px;line-height:1.45;display:flex;gap:10px;align-items:flex-start}
.vtb__cijfer{flex:none;width:30px;height:30px;display:grid;place-items:center;border-radius:4px;background:#F5480F;color:#fff;font:700 14px 'JetBrains Mono',monospace}
.vtb__who{margin:0;font:500 10.5px 'JetBrains Mono',monospace;color:rgba(10,10,10,.55)}
@media (max-width:420px){.vtb{padding:11px 12px 10px}.vtb__tab{font-size:11.5px;padding:7px 6px 8px}.vtb__kick{font-size:12.5px}.vtb__dl{grid-template-columns:1fr}.vtb__dl div{padding:4px 0}.vtb__lead{font-size:12.5px}.vtb__p{font-size:11.5px}.vtb__rev{font-size:12px}}
::view-transition-group(vtb-ind){animation-duration:.34s;animation-timing-function:cubic-bezier(.3,.8,.2,1)}
::view-transition-old(vtb-ind){display:none}
::view-transition-new(vtb-ind){animation:none;height:100%;width:100%}
::view-transition-group(vtb-panel){overflow:clip}
:active-view-transition-type(vtb-rechts)::view-transition-old(vtb-panel){animation:vtb-uitl .15s ease-in both}
:active-view-transition-type(vtb-rechts)::view-transition-new(vtb-panel){animation:vtb-inr .3s cubic-bezier(.2,.7,.2,1) .12s both}
:active-view-transition-type(vtb-links)::view-transition-old(vtb-panel){animation:vtb-uitr .15s ease-in both}
:active-view-transition-type(vtb-links)::view-transition-new(vtb-panel){animation:vtb-inl .3s cubic-bezier(.2,.7,.2,1) .12s both}
@keyframes vtb-uitl{to{opacity:0;transform:translateX(-24px)}}
@keyframes vtb-inr{from{opacity:0;transform:translateX(24px)}}
@keyframes vtb-uitr{to{opacity:0;transform:translateX(24px)}}
@keyframes vtb-inl{from{opacity:0;transform:translateX(-24px)}}
@media (prefers-reduced-motion:reduce){::view-transition-group(vtb-ind),::view-transition-group(vtb-panel),::view-transition-old(vtb-panel),::view-transition-new(vtb-panel){animation:none!important}}// Tabs met glijdende onderstreping · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.vtb');if(!w)return;var tabs=[].slice.call(w.querySelectorAll('.vtb__tab')),ind=w.querySelector('.vtb__ind'),wrap=w.querySelector('.vtb__panels');
var rm=matchMedia('(prefers-reduced-motion: reduce)');var cur=0,busy=false;var hasTypes=typeof ViewTransition!=='undefined'&&'types' in ViewTransition.prototype;
/* id's uniek maken als het blok vaker op de pagina staat */
var uid='vtb'+Math.random().toString(36).slice(2,7);tabs.forEach(function(t,k){var p=w.querySelector('#'+t.getAttribute('aria-controls'));t.id=uid+'-t'+k;p.id=uid+'-p'+k;t.setAttribute('aria-controls',p.id);p.setAttribute('aria-labelledby',t.id);});
function panelOf(t){return w.querySelector('#'+t.getAttribute('aria-controls'));}
function show(n){tabs.forEach(function(t,k){var on=k===n;t.setAttribute('aria-selected',on?'true':'false');t.tabIndex=on?0:-1;panelOf(t).hidden=!on;});tabs[n].appendChild(ind);cur=n;}
function sel(n,focus){if(n===cur||busy){if(focus)tabs[n].focus();return;}if(focus)tabs[n].focus();
if(!document.startViewTransition||rm.matches){show(n);return;}busy=true;ind.style.viewTransitionName='vtb-ind';wrap.style.viewTransitionName='vtb-panel';
var ty=n>cur?'vtb-rechts':'vtb-links';var t=hasTypes?document.startViewTransition({update:function(){show(n);},types:[ty]}):document.startViewTransition(function(){show(n);});
t.finished.finally(function(){ind.style.viewTransitionName='';wrap.style.viewTransitionName='';busy=false;});}
tabs.forEach(function(t,k){t.addEventListener('click',function(){sel(k,false);});t.addEventListener('keydown',function(e){var n=null;
if(e.key==='ArrowRight')n=(k+1)%tabs.length;else if(e.key==='ArrowLeft')n=(k-1+tabs.length)%tabs.length;else if(e.key==='Home')n=0;else if(e.key==='End')n=tabs.length-1;
if(n!==null){e.preventDefault();sel(n,true);}});});
}
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 →