Eigen scrollbalk voor een lijst New
A thin custom scrollbar under a horizontal product list: drag the thumb, click the line to jump a page or use arrows, Page Up/Down, Home and End on the bar (role="scrollbar" with aria-valuenow). Trackpad, touch and shift-scroll keep working natively; the bar follows. Hides itself when everything fits. Pointer events with pointer capture, scroll-snap on the list.
Nieuw binnen
Alle 312 producten
Bank Lisse, antraciet velours
€ 1.249

Eettafel Vecht, massief eiken
€ 1.095

Boekenkast Delden, noten
€ 879

Hanglamp Rietveld, rotan
€ 189

Loungeset Texel, teak
€ 1.649

Inmeten aan huis, Zwolle e.o.
Gratis
How to use it
- Paste the HTML where the components 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.
<!-- Eigen scrollbalk voor een lijst · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="sbe">
<div class="sbe__head"><h3 class="sbe__h">Nieuw binnen</h3><a class="sbe__all" href="#scrollbalk-eigen">Alle 312 producten</a></div>
<ul class="sbe__list" id="sbe-lijst" tabindex="0" aria-label="Nieuw binnen, horizontaal scrollbare lijst">
<li class="sbe__it"><img src="https://neddev.com/lab-media/categorie-panelen-1.webp" alt="" loading="lazy"><p class="sbe__n">Bank Lisse, antraciet velours</p><p class="sbe__pr">€ 1.249</p></li>
<li class="sbe__it"><img src="https://neddev.com/lab-media/categorie-panelen-2.webp" alt="" loading="lazy"><p class="sbe__n">Eettafel Vecht, massief eiken</p><p class="sbe__pr">€ 1.095</p></li>
<li class="sbe__it"><img src="https://neddev.com/lab-media/categorie-panelen-3.webp" alt="" loading="lazy"><p class="sbe__n">Boekenkast Delden, noten</p><p class="sbe__pr">€ 879</p></li>
<li class="sbe__it"><img src="https://neddev.com/lab-media/categorie-panelen-4.webp" alt="" loading="lazy"><p class="sbe__n">Hanglamp Rietveld, rotan</p><p class="sbe__pr">€ 189</p></li>
<li class="sbe__it"><img src="https://neddev.com/lab-media/categorie-panelen-5.webp" alt="" loading="lazy"><p class="sbe__n">Loungeset Texel, teak</p><p class="sbe__pr">€ 1.649</p></li>
<li class="sbe__it"><img src="https://neddev.com/lab-media/viewport-kader-1.webp" alt="" loading="lazy"><p class="sbe__n">Inmeten aan huis, Zwolle e.o.</p><p class="sbe__pr">Gratis</p></li>
</ul>
<div class="sbe__track" role="scrollbar" aria-controls="sbe-lijst" aria-orientation="horizontal" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" aria-label="Scrollpositie Nieuw binnen" tabindex="0"><div class="sbe__line"><div class="sbe__thumb"></div></div></div>
</div>
</div>/* Eigen scrollbalk voor een lijst · NedDev · eigen werk. */
.sbe{position:absolute;inset:0;display:flex;flex-direction:column;background:#fff;color:#0a0a0a;font-family:'Switzer',sans-serif;container-type:size;text-align:left;padding:12px 0 6px}
.sbe *,.sbe *::before,.sbe *::after{box-sizing:border-box}
.sbe__head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;padding:0 16px 8px}
.sbe__h{margin:0;font:700 18px/1.1 'Switzer',sans-serif;letter-spacing:-.02em}
.sbe__all{font:500 12.5px/1.2 'Switzer',sans-serif;color:#0a0a0a;text-decoration:underline;text-underline-offset:3px;transition:color .16s}
.sbe__all:hover{color:#b8330a}
.sbe__all:focus-visible{outline:2px solid #F5480F;outline-offset:2px;border-radius:4px}
.sbe__list{flex:1;min-height:0;display:flex;gap:10px;margin:0;padding:0 16px;list-style:none;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x proximity;scroll-padding:0 16px;scrollbar-width:none;outline:none}
.sbe__list::-webkit-scrollbar{display:none}
.sbe__list:focus-visible{outline:2px solid #F5480F;outline-offset:-2px}
.sbe__it{flex:0 0 clamp(120px,36cqi,170px);scroll-snap-align:start;display:flex;flex-direction:column;gap:4px}
.sbe__it img{display:block;width:100%;flex:1;min-height:0;object-fit:cover;border-radius:4px;background:#e4e2de}
.sbe__n{margin:2px 0 0;font:500 12.5px/1.25 'Switzer',sans-serif;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sbe__pr{margin:0;font:600 12.5px/1.2 'Switzer',sans-serif}
.sbe__track{flex:none;position:relative;height:22px;margin:4px 16px 0;cursor:pointer;touch-action:none;outline:none}
.sbe__track[hidden]{display:none}
.sbe__line{position:absolute;left:0;right:0;top:50%;height:2px;transform:translateY(-50%);background:#e4e2de;transition:height .15s}
.sbe__thumb{position:absolute;top:0;bottom:0;left:0;width:40px;background:#0a0a0a;border-radius:1px;cursor:grab}
.sbe__track:hover .sbe__line,.sbe__track.is-drag .sbe__line,.sbe__track:focus-visible .sbe__line{height:4px}
.sbe__track.is-drag .sbe__thumb{cursor:grabbing;background:#F5480F}
.sbe__track:focus-visible{outline:2px solid #F5480F;outline-offset:2px;border-radius:4px}
@media (prefers-reduced-motion:reduce){.sbe__line{transition:none}}// Eigen scrollbalk voor een lijst · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.sbe');if(!w)return;
var list=w.querySelector('.sbe__list'),track=w.querySelector('.sbe__track'),line=w.querySelector('.sbe__line'),thumb=w.querySelector('.sbe__thumb');
var rm=matchMedia('(prefers-reduced-motion: reduce)').matches,drag=null;
function m(){var sw=list.scrollWidth,cw=list.clientWidth,tw=line.clientWidth,th=Math.max(32,tw*cw/sw);return{max:sw-cw,tw:tw,th:th,cw:cw};}
function upd(){var d=m();track.hidden=d.max<=1;if(d.max<=1)return;var p=list.scrollLeft/d.max;thumb.style.width=d.th+'px';thumb.style.transform='translateX('+((d.tw-d.th)*p).toFixed(1)+'px)';track.setAttribute('aria-valuenow',Math.round(p*100));}
list.addEventListener('scroll',upd,{passive:true});
function to(x,smooth){list.scrollTo({left:x,behavior:smooth&&!rm?'smooth':'auto'});}
thumb.addEventListener('pointerdown',function(e){e.preventDefault();e.stopPropagation();var d=m();drag={x:e.clientX,s:list.scrollLeft,r:d.max/Math.max(1,d.tw-d.th)};list.style.scrollSnapType='none';track.classList.add('is-drag');thumb.setPointerCapture(e.pointerId);});
thumb.addEventListener('pointermove',function(e){if(!drag)return;list.scrollLeft=drag.s+(e.clientX-drag.x)*drag.r;});
function end(){if(!drag)return;drag=null;list.style.scrollSnapType='';track.classList.remove('is-drag');}
thumb.addEventListener('pointerup',end);thumb.addEventListener('pointercancel',end);
track.addEventListener('pointerdown',function(e){if(e.target===thumb)return;var tr=thumb.getBoundingClientRect(),d=m();to(list.scrollLeft+(e.clientX<tr.left?-1:1)*d.cw*.85,true);});
track.addEventListener('keydown',function(e){var d=m(),x=null;if(e.key==='ArrowRight')x=list.scrollLeft+d.max*.1;else if(e.key==='ArrowLeft')x=list.scrollLeft-d.max*.1;else if(e.key==='PageDown')x=list.scrollLeft+d.cw*.85;else if(e.key==='PageUp')x=list.scrollLeft-d.cw*.85;else if(e.key==='Home')x=0;else if(e.key==='End')x=d.max;if(x!==null){e.preventDefault();to(x,e.key!=='ArrowRight'&&e.key!=='ArrowLeft');}});
if('ResizeObserver' in window)new ResizeObserver(upd).observe(list);
[].forEach.call(list.querySelectorAll('img'),function(im){im.addEventListener('load',upd);});
upd();
}
init(document.querySelector('.jouw-container'));
More components
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 →