Lightbox-galerij New
A photo grid where the clicked image zooms from its own position into a lightbox with caption, counter, arrows, swipe and Esc. For portfolios of garden designers, interior builders and photographers.
Tuinontwerp Groenewoud · Wassenaar6 tuinen
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.
<!-- Lightbox-galerij · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="lbx"><div class="lbx__hd"><span>Tuinontwerp Groenewoud · Wassenaar</span><span>6 tuinen</span></div><div class="lbx__grid">
<button class="lbx__th lbx__a0" type="button" data-c="Stadstuin · Utrecht · 42 m2" aria-label="Open foto: Stadstuin Utrecht"></button>
<button class="lbx__th lbx__a1" type="button" data-c="Vijvertuin · Wassenaar · 180 m2" aria-label="Open foto: Vijvertuin Wassenaar"></button>
<button class="lbx__th lbx__a2" type="button" data-c="Terras met pergola · Leiden" aria-label="Open foto: Terras met pergola Leiden"></button>
<button class="lbx__th lbx__a3" type="button" data-c="Borderbeplanting · Oegstgeest" aria-label="Open foto: Borderbeplanting Oegstgeest"></button>
<button class="lbx__th lbx__a4" type="button" data-c="Moestuin in bakken · Voorschoten" aria-label="Open foto: Moestuin Voorschoten"></button>
<button class="lbx__th lbx__a5" type="button" data-c="Daktuin · Den Haag · 64 m2" aria-label="Open foto: Daktuin Den Haag"></button></div>
<div class="lbx__ov" role="dialog" aria-modal="true" aria-label="Fotoweergave"><div class="lbx__stage"><div class="lbx__big"></div></div>
<button class="lbx__nv lbx__nv--p" type="button" aria-label="Vorige foto"><svg viewBox="0 0 16 16" width="14" height="14"><path d="M10 3L5 8l5 5" fill="none" stroke="currentColor" stroke-width="1.8"/></svg></button>
<button class="lbx__nv lbx__nv--n" type="button" aria-label="Volgende foto"><svg viewBox="0 0 16 16" width="14" height="14"><path d="M6 3l5 5-5 5" fill="none" stroke="currentColor" stroke-width="1.8"/></svg></button>
<button class="lbx__x" type="button" aria-label="Sluit"><svg viewBox="0 0 16 16" width="12" height="12"><path d="M3 3l10 10M13 3L3 13" stroke="currentColor" stroke-width="1.8"/></svg></button>
<div class="lbx__bar"><span class="lbx__cap"></span><span class="lbx__n"></span></div></div></div>
</div>/* Lightbox-galerij · NedDev · eigen werk. */
.lbx{position:absolute;inset:0;background:#f4f3f1;font-family:'Switzer',system-ui,sans-serif;padding:10px;display:flex;flex-direction:column;gap:7px;overflow:hidden}
.lbx__hd{display:flex;justify-content:space-between;gap:8px;font:500 9.5px 'JetBrains Mono',monospace;letter-spacing:.08em;text-transform:uppercase;color:#6b6762;white-space:nowrap;overflow:hidden}
.lbx__grid{flex:1;display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:1fr 1fr;gap:5px;min-height:0}
.lbx__th{appearance:none;border:0;padding:0;border-radius:3px;cursor:zoom-in;transition:transform .3s,filter .3s;min-height:0}
.lbx__th:hover{transform:scale(.97);filter:brightness(1.05)}.lbx__th:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.lbx__a0{background:radial-gradient(circle at 70% 55%,#4f6b45 0 22%,transparent 23%),radial-gradient(circle at 82% 30%,#6f8a5f 0 12%,transparent 13%),linear-gradient(90deg,#d9cfc0 0 30%,transparent 30%),repeating-linear-gradient(0deg,#bfb4a3 0 1px,#e2d9cb 1px 14px)}
.lbx__a1{background:radial-gradient(58% 38% at 50% 62%,#567a86 0 60%,#3f5e68 61% 68%,transparent 69%),radial-gradient(circle at 18% 22%,#3e5636 0 12%,transparent 13%),linear-gradient(#7d9a63,#5f7c4b)}
.lbx__a2{background:repeating-linear-gradient(90deg,#0a0a0a 0 4px,transparent 4px 30px),linear-gradient(180deg,#0a0a0a 0 9%,transparent 9%),linear-gradient(180deg,transparent 72%,#b9a68a 72%),linear-gradient(#efe6d8,#d8c9b2)}
.lbx__a3{background:radial-gradient(circle at 20% 70%,#F5480F 0 7%,transparent 7.5%),radial-gradient(circle at 45% 60%,#f0a35e 0 6%,transparent 6.5%),radial-gradient(circle at 72% 72%,#F5480F 0 8%,transparent 8.5%),radial-gradient(circle at 88% 58%,#e9d7b0 0 5%,transparent 5.5%),linear-gradient(180deg,#e9e4da 0 52%,#4d6a42 52%)}
.lbx__a4{background:linear-gradient(180deg,transparent 0 50%,rgba(255,255,255,.18) 50% 52%,transparent 52%),repeating-linear-gradient(90deg,#6b4f36 0 6px,#3f5a35 6px 40px,#6b4f36 40px 46px,#b9a68a 46px 62px)}
.lbx__a5{background:radial-gradient(circle at 30% 62%,#F5480F 0 5%,transparent 5.5%),radial-gradient(circle at 42% 62%,#F5480F 0 5%,transparent 5.5%),linear-gradient(180deg,#dfe6ea 0 40%,#0a0a0a 40% 42%,#8aa070 42%)}
.lbx__ov{position:absolute;inset:0;z-index:5;background:rgba(10,10,10,.94);visibility:hidden;opacity:0;transition:opacity .3s,visibility 0s .3s}
.lbx.is-open .lbx__ov{visibility:visible;opacity:1;transition:opacity .3s}
.lbx__stage{position:absolute;left:42px;right:42px;top:12px;bottom:36px}
.lbx__big{position:absolute;inset:0;border-radius:3px;transform-origin:0 0;will-change:transform}
.lbx__nv,.lbx__x{appearance:none;position:absolute;border:1px solid rgba(255,255,255,.25);background:rgba(10,10,10,.6);color:#fff;border-radius:50%;width:28px;height:28px;display:grid;place-items:center;cursor:pointer;transition:background .2s,border-color .2s}
.lbx__nv:hover,.lbx__x:hover{background:#F5480F;border-color:#F5480F}
.lbx__nv:focus-visible,.lbx__x:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.lbx__nv{top:calc(50% - 26px)}.lbx__nv--p{left:7px}.lbx__nv--n{right:7px}.lbx__x{top:8px;right:7px;width:26px;height:26px}
.lbx__bar{position:absolute;left:42px;right:42px;bottom:9px;display:flex;justify-content:space-between;gap:8px;color:#fff;font-size:12px;font-weight:600}
.lbx__n{font:500 10px 'JetBrains Mono',monospace;color:#a8a39c;font-variant-numeric:tabular-nums}
@media (prefers-reduced-motion:reduce){.lbx__ov{transition:none}}// Lightbox-galerij · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
root=root.querySelector('.lbx')||root;
var ths=[].slice.call(root.querySelectorAll('.lbx__th')),ov=root.querySelector('.lbx__ov'),big=root.querySelector('.lbx__big'),cap=root.querySelector('.lbx__cap'),num=root.querySelector('.lbx__n');
var rm=matchMedia('(prefers-reduced-motion: reduce)').matches,cur=-1,touched=false,E='cubic-bezier(.2,.8,.2,1)';
function art(i){big.className='lbx__big lbx__a'+i;cap.textContent=ths[i].getAttribute('data-c');num.textContent=(i+1)+' / '+ths.length;}
function flip(i){var a=ths[i].getBoundingClientRect(),b=big.getBoundingClientRect();return'translate('+(a.left-b.left)+'px,'+(a.top-b.top)+'px) scale('+(a.width/b.width)+','+(a.height/b.height)+')';}
function open(i){cur=i;art(i);root.classList.add('is-open');if(!rm)big.animate([{transform:flip(i),borderRadius:'6px'},{transform:'none',borderRadius:'3px'}],{duration:520,easing:E});root.querySelector('.lbx__x').focus({preventScroll:true});}
function close(){if(cur<0)return;var i=cur;cur=-1;if(rm){root.classList.remove('is-open');return;}
var an=big.animate([{transform:'none'},{transform:flip(i)}],{duration:420,easing:E,fill:'forwards'});setTimeout(function(){root.classList.remove('is-open');},200);an.onfinish=function(){an.cancel();};if(touched)ths[i].focus({preventScroll:true});}
function nav(d){if(cur<0)return;var n=(cur+d+ths.length)%ths.length;if(rm){cur=n;art(n);return;}
big.animate([{transform:'none',opacity:1},{transform:'translateX('+(-d*40)+'px)',opacity:0}],{duration:180,easing:'ease-in'}).onfinish=function(){cur=n;art(n);big.animate([{transform:'translateX('+(d*40)+'px)',opacity:0},{transform:'none',opacity:1}],{duration:320,easing:E});};}
ths.forEach(function(t,i){t.addEventListener('click',function(){touched=true;open(i);});});
root.querySelector('.lbx__x').addEventListener('click',function(){touched=true;close();});
root.querySelector('.lbx__nv--p').addEventListener('click',function(){touched=true;nav(-1);});
root.querySelector('.lbx__nv--n').addEventListener('click',function(){touched=true;nav(1);});
ov.addEventListener('click',function(e){if(e.target===ov){touched=true;close();}});
root.addEventListener('keydown',function(e){if(cur<0)return;touched=true;if(e.key==='Escape')close();if(e.key==='ArrowRight')nav(1);if(e.key==='ArrowLeft')nav(-1);});
var sx=null;ov.addEventListener('pointerdown',function(e){sx=e.clientX;});ov.addEventListener('pointerup',function(e){if(sx===null)return;var dx=e.clientX-sx;sx=null;if(Math.abs(dx)>40){touched=true;nav(dx<0?1:-1);}});
if(!rm){setTimeout(function(){if(!touched){cur=-1;open(1);}},900);setTimeout(function(){if(!touched&&cur>=0)close();},3600);}
}
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 →