Paginering: nummers, compact, laad meer Nieuw
Drie varianten voor blog, vacatures of projecten: genummerd met vorige/volgende, ellipsis en aria-current, een compacte mobiele variant (pagina 5 van 12) en "laad meer" met teller, laadstaat, focus op het eerste nieuwe bericht en een eindstaat. Echte -links zodat Google elke pagina vindt; een container query maakt de knoppen smaller in een smalle kolom.
Nieuws · Hoveniersbedrijf Groenrijk
Zo gebruik je het
- Plak de HTML op de plek waar het onderdeel moet komen.
- Zet de CSS in je stylesheet. Alle klassen hebben een eigen voorvoegsel, dus niets botst met je eigen opmaak.
- Voeg de JavaScript toe en roep init() aan met het element waar de HTML in staat.
<!-- Paginering: nummers, compact, laad meer · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="pgn">
<div class="pgn__top"><span class="pgn__eyebrow">Nieuws · Hoveniersbedrijf Groenrijk</span>
<div class="pgn__mode" role="group" aria-label="Variant"><button type="button" aria-pressed="true" data-m="num">Nummers</button><button type="button" aria-pressed="false" data-m="cmp">Compact</button><button type="button" aria-pressed="false" data-m="more">Laad meer</button></div></div>
<ul class="pgn__list"></ul>
<nav class="pgn__nav" aria-label="Paginering"></nav>
<p class="pgn__sr" aria-live="polite"></p>
</div>
</div>/* Paginering: nummers, compact, laad meer · NedDev · eigen werk. */
.pgn{--ink:#0a0a0a;--pop:#F5480F;--pd:#b83a0b;--line:rgba(10,10,10,.12);position:absolute;inset:0;display:flex;flex-direction:column;padding:12px 16px;gap:8px;font-family:'Switzer',system-ui,sans-serif;color:var(--ink);background:#fff;container-type:inline-size}
.pgn__top{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:6px 10px}
.pgn__eyebrow{font:600 9.5px/1.2 'JetBrains Mono',monospace;letter-spacing:.12em;text-transform:uppercase;color:#5b5b5b}
.pgn__mode{display:inline-flex;border:1px solid var(--ink);border-radius:100px;padding:2px}
.pgn__mode button{font:600 9.5px/1 'JetBrains Mono',monospace;letter-spacing:.06em;text-transform:uppercase;padding:6px 9px;border:0;border-radius:100px;background:none;color:var(--ink);cursor:pointer;transition:background .15s,color .15s}
.pgn__mode button[aria-pressed=true]{background:var(--ink);color:#fff}
.pgn button:focus-visible,.pgn a:focus-visible,.pgn li:focus-visible{outline:2px solid var(--pd);outline-offset:2px}
.pgn__list{list-style:none;margin:0;padding:0;flex:1;min-height:0;overflow:auto}
.pgn__list li{border-bottom:1px solid var(--line);border-radius:2px}
.pgn__list a{display:block;padding:7px 0;color:var(--ink);text-decoration:none}
.pgn__list a:hover .pgn__t{text-decoration:underline;text-decoration-color:var(--pop);text-decoration-thickness:2px;text-underline-offset:3px}
.pgn__meta{display:block;font:500 10px/1.3 'JetBrains Mono',monospace;letter-spacing:.06em;text-transform:uppercase;color:#5b5b5b}
.pgn__t{display:block;font-size:13.5px;font-weight:600;line-height:1.3}
.pgn__list li.is-new{animation:pgn-in .35s ease both}
@keyframes pgn-in{from{opacity:0;transform:translateY(6px)}}
.pgn__nav{display:flex;align-items:center;justify-content:center;gap:4px;min-height:34px}
.pgn__nav a,.pgn__gap,.pgn__step{display:inline-grid;place-items:center;min-width:32px;height:32px;padding:0 6px;border-radius:4px;font:600 12.5px/1 'Switzer',system-ui,sans-serif;font-variant-numeric:tabular-nums;color:var(--ink);text-decoration:none;transition:background .15s,color .15s}
.pgn__nav a:hover{background:#f0eeea}
.pgn__nav a[aria-current=page]{background:var(--ink);color:#fff}
.pgn__nav .pgn__step{display:inline-flex;align-items:center;gap:6px;padding:0 10px;border:1px solid var(--line);white-space:nowrap}
.pgn__step[aria-disabled=true]{color:#9a9a9a;border-color:#ebe9e5;cursor:not-allowed}
.pgn__gap{min-width:20px;color:#5b5b5b}
.pgn__cmp{font:600 12.5px/1 'Switzer',system-ui,sans-serif;padding:0 12px;font-variant-numeric:tabular-nums;white-space:nowrap}
.pgn__more{display:flex;align-items:center;gap:12px;width:100%}
.pgn__mc{flex:1;min-width:0;font-size:11.5px;color:#5b5b5b}
.pgn__mbar{display:block;height:3px;margin-top:5px;background:#e1ded8;border-radius:2px;overflow:hidden}
.pgn__mbar span{display:block;height:100%;background:var(--ink);transition:width .3s ease}
.pgn__load{display:inline-flex;align-items:center;gap:8px;padding:9px 14px;border:1px solid var(--ink);border-radius:4px;background:#fff;color:var(--ink);font:600 12px/1 'Switzer',system-ui,sans-serif;cursor:pointer;white-space:nowrap;transition:background .15s,color .15s}
.pgn__load:hover{background:var(--ink);color:#fff}
.pgn__load[aria-busy=true]::before{content:'';width:11px;height:11px;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:pgn-spin .7s linear infinite}
.pgn__load:disabled{background:#f0eeea;color:#5b5b5b;border-color:#e1ded8;cursor:default}
@keyframes pgn-spin{to{transform:rotate(360deg)}}
.pgn__sr,.pgn__vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;margin:0}
@container (max-width:440px){.pgn__lab{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}.pgn__step{padding:0 8px;min-width:32px}.pgn__nav a,.pgn__gap{min-width:28px;padding:0 4px}.pgn__nav{gap:2px}}
@media (prefers-reduced-motion:reduce){.pgn__list li.is-new{animation:none}}// Paginering: nummers, compact, laad meer · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.pgn');if(!w)return;
var T=['Zo bereid je je gazon voor op de winter','Bladblazer of hark: wat is beter voor je tuin?','Project: stadstuin van 40 m² in Utrecht-Oost','Wanneer snoei je een hortensia?','Sedumdak op je schuur: kosten en onderhoud','Vergunning nodig voor een schutting?','Project: tegels eruit, groen erin in Amersfoort','Vijf vaste planten die droogte goed aankunnen','Regenwater opvangen met een infiltratiekrat','Houten of composiet vlonder?','Project: daktuin op een kantoor in Zwolle','Gazon verticuteren in het voorjaar','Buxusmot herkennen en aanpakken','Subsidie voor een groen dak per gemeente','Project: achtertuin met keramische tegels in Ede','Bomen planten: de beste maand','Kunstgras of echt gras, eerlijk vergeleken','Moestuinbakken van cortenstaal','Project: voortuin zonder onderhoud in Baarn','Tuinverlichting op zonne-energie','Haag planten: liguster, beuk of taxus','Waterdoorlatende bestrating uitgelegd','Project: bedrijfstuin bij een zorgcentrum','Ons team groeit: drie nieuwe hoveniers'];
var D=['zo','ma','di','wo','do','vr','za'],M=['jan','feb','mrt','apr','mei','jun','jul','aug','sep','okt','nov','dec'];
function date(i){var d=new Date(2026,9,6-i*5);return D[d.getDay()]+' '+d.getDate()+' '+M[d.getMonth()];}
var list=w.querySelector('.pgn__list'),nav=w.querySelector('.pgn__nav'),sr=w.querySelector('.pgn__sr'),PER=2,N=12,page=5,mode='num',shown=6,MORE=6;
function item(i,isNew){var li=document.createElement('li');var proj=T[i].indexOf('Project:')===0;li.innerHTML='<a href="#bericht-'+(i+1)+'"><span class="pgn__meta">'+date(i)+' · '+(proj?'Project':'Advies')+'</span><span class="pgn__t">'+(proj?T[i].charAt(9).toUpperCase()+T[i].slice(10):T[i])+'</span></a>';if(isNew){li.className='is-new';li.tabIndex=-1;}return li;}
function pages(c){var r=w.clientWidth<360?0:1,a=[1],s=Math.max(2,c-r),e=Math.min(N-1,c+r);if(c<=3){s=2;e=Math.max(e,r?4:3);}if(c>=N-2){s=Math.min(s,r?N-3:N-2);e=N-1;}if(s>2)a.push(0);for(var i=s;i<=e;i++)a.push(i);if(e<N-1)a.push(0);a.push(N);return a;}
function link(p,txt,cls,lab){return p?'<a class="'+cls+'" href="?pagina='+p+'" data-p="'+p+'"'+(lab?' aria-label="'+lab+'"':'')+(cls==='pgn__step'?(txt==='prev'?' rel="prev"':' rel="next"'):'')+'>'+(txt==='prev'?'<span aria-hidden="true">←</span><span class="pgn__lab">Vorige</span>':txt==='next'?'<span class="pgn__lab">Volgende</span><span aria-hidden="true">→</span>':txt)+'</a>'
:'<span class="'+cls+'" aria-disabled="true" role="link">'+(txt==='prev'?'<span aria-hidden="true">←</span><span class="pgn__lab">Vorige</span>':'<span class="pgn__lab">Volgende</span><span aria-hidden="true">→</span>')+'</span>';}
function render(focusSel){list.innerHTML='';nav.setAttribute('aria-label','Paginering');
if(mode==='more'){for(var i=0;i<shown;i++)list.appendChild(item(i));var end=shown>=T.length;
nav.innerHTML='<div class="pgn__more"><div class="pgn__mc">'+(end?'Alle '+T.length+' berichten geladen':'Je zag '+shown+' van '+T.length+' berichten')+'<span class="pgn__mbar"><span style="width:'+(shown/T.length*100)+'%"></span></span></div><button class="pgn__load" type="button"'+(end?' disabled':'')+'>'+(end?'Alles geladen':'Laad meer')+'</button></div>';
var b=nav.querySelector('.pgn__load');b.addEventListener('click',function(){if(b.getAttribute('aria-busy'))return;b.setAttribute('aria-busy','true');b.textContent='Laden';
setTimeout(function(){var from=shown;shown=Math.min(T.length,shown+MORE);render();var lis=list.children;for(var j=from;j<shown;j++){lis[j].classList.add('is-new');lis[j].tabIndex=-1;}lis[from].focus();sr.textContent=(shown-from)+' berichten geladen, '+shown+' van '+T.length;},650);});
if(focusSel){var f=nav.querySelector(focusSel);if(f)f.focus();}return;}
var s=(page-1)*PER;for(var k=s;k<s+PER;k++)list.appendChild(item(k));
var h=link(page>1?page-1:0,'prev','pgn__step','Vorige pagina');
if(mode==='num')pages(page).forEach(function(p){h+=p?(p===page?'<a href="?pagina='+p+'" data-p="'+p+'" aria-current="page" aria-label="Pagina '+p+', huidige pagina">'+p+'</a>':link(p,String(p),'','Pagina '+p)):'<span class="pgn__gap" aria-hidden="true">…</span>';});
else h+='<span class="pgn__cmp">Pagina '+page+' van '+N+'</span>';
h+=link(page<N?page+1:0,'next','pgn__step','Volgende pagina');nav.innerHTML=h;
if(focusSel){var el=nav.querySelector(focusSel)||nav.querySelector('[aria-current=page]')||nav.querySelector('a');if(el)el.focus();}}
nav.addEventListener('click',function(e){var a=e.target.closest('a[data-p]');if(!a)return;e.preventDefault();var p=+a.dataset.p,rel=a.getAttribute('rel');page=p;
render(rel?'[rel='+rel+']':'[aria-current=page]');sr.textContent='Pagina '+page+' van '+N;});
w.querySelectorAll('.pgn__mode button').forEach(function(b){b.addEventListener('click',function(){mode=b.dataset.m;shown=6;w.querySelectorAll('.pgn__mode button').forEach(function(x){x.setAttribute('aria-pressed',x===b);});render();});});
if('ResizeObserver' in window){var lw=0;new ResizeObserver(function(){var cw=w.clientWidth<360;if(cw!==lw){lw=cw;if(mode!=='more')render();}}).observe(w);}
render();
}
init(document.querySelector('.jouw-container'));
Meer uit navigatie & menu's
Iets gezien dat je mooi vindt?
Zet het in je selectie en stuur hem op. Dan bouwen we je site eromheen, in jouw huisstijl.
Neem contact op →