Shop de look Nieuw
Punten op een sfeerfoto van een woonkamer; een klik opent een productkaartje naast het punt met prijs en een knop voor het mandje, onderin telt een balk mee en kun je de hele look in één keer toevoegen. Pijltjestoetsen springen tussen de punten, Esc sluit. De foto vult de tegel als cover en de punten rekenen mee, dus ze blijven op de bank en de lamp staan. Voor webshops in wonen, mode en tuin; de brede uitleg-variant voor techniek is product-hotspots.
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.
<!-- Shop de look · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="sdl">
<div class="sdl__pic">
<img class="sdl__img" src="https://neddev.com/lab-media/shop-de-look-1.webp" alt="Lichte woonkamer met grijze bank, ronde eiken salontafel, messing vloerlamp en een vijgenboom" width="1200" height="655">
<button class="sdl__pt" type="button" style="--x:37%;--y:57%" data-i="0" aria-expanded="false" aria-label="Bank Lund">
</button><button class="sdl__pt" type="button" style="--x:53%;--y:76%" data-i="1" aria-expanded="false" aria-label="Salontafel Ronde Eik">
</button><button class="sdl__pt" type="button" style="--x:72%;--y:38%" data-i="2" aria-expanded="false" aria-label="Vloerlamp Mira">
</button><button class="sdl__pt" type="button" style="--x:27%;--y:44%" data-i="3" aria-expanded="false" aria-label="Vijgenboom in pot"></button>
</div>
<div class="sdl__card" role="dialog" aria-label="Product" hidden>
<b class="sdl__nm"></b><span class="sdl__me"></span>
<div class="sdl__row"><span class="sdl__pr"></span><button class="sdl__add" type="button" aria-pressed="false">In mandje</button></div>
</div>
<div class="sdl__bar"><span class="sdl__cnt" aria-live="polite">0 van 4 in je mandje</span><button class="sdl__all" type="button">Hele look · € 2.016</button></div>
</div>
</div>/* Shop de look · NedDev · eigen werk. */
.sdl{position:absolute;inset:0;overflow:hidden;background:#0a0a0a;color:#0a0a0a;font-family:'Switzer',sans-serif;text-align:left;container-type:size}
.sdl__pic{position:absolute;left:50%;top:44%;width:max(100cqw,calc(100cqh * 1.832));aspect-ratio:1200/655;transform:translate(-50%,-50%)}
.sdl__img{display:block;width:100%;height:100%}
.sdl__pt{position:absolute;left:var(--x);top:var(--y);width:26px;height:26px;margin:-13px 0 0 -13px;padding:0;border:2px solid #fff;border-radius:50%;background:rgba(10,10,10,.35);cursor:pointer;display:grid;place-items:center}
.sdl__pt::before{content:"";width:10px;height:10px;border-radius:50%;background:#fff;transition:background .2s,transform .2s}
.sdl__pt::after{content:"";position:absolute;inset:-2px;border:2px solid #fff;border-radius:50%;animation:sdl-ring 2.4s ease-out infinite;pointer-events:none}
.sdl__pt:hover::before,.sdl__pt[aria-expanded="true"]::before{background:#F5480F;transform:scale(1.2)}
.sdl__pt.is-in::before{background:#F5480F}
.sdl__pt:focus-visible{outline:2px solid #F5480F;outline-offset:3px}
@keyframes sdl-ring{0%{transform:scale(1);opacity:.8}80%,100%{transform:scale(1.9);opacity:0}}
.sdl__card{position:absolute;width:172px;padding:10px 12px;background:#fff;border-radius:8px;box-shadow:0 8px 24px rgba(10,10,10,.18);display:flex;flex-direction:column;gap:2px}
.sdl__card[hidden]{display:none}
.sdl__nm{font:600 14px/1.25 'Switzer',sans-serif}
.sdl__me{font:400 12px/1.35 'Switzer',sans-serif;color:#5c5a57}
.sdl__row{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:6px}
.sdl__pr{font:600 14px/1 'Switzer',sans-serif;font-variant-numeric:tabular-nums}
.sdl__add{min-height:28px;padding:0 10px;border:0;border-radius:4px;background:#0a0a0a;color:#fff;font:500 12px/1 'Switzer',sans-serif;cursor:pointer;white-space:nowrap}
.sdl__add[aria-pressed="true"]{background:#F5480F}
.sdl__add:focus-visible,.sdl__all:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.sdl__bar{position:absolute;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 10px 8px 14px;background:#fff;border-top:1px solid rgba(10,10,10,.08)}
.sdl__cnt{font:500 13px/1.2 'Switzer',sans-serif}
.sdl__all{min-height:30px;padding:0 12px;border:0;border-radius:4px;background:#F5480F;color:#fff;font:600 13px/1 'Switzer',sans-serif;cursor:pointer;white-space:nowrap}
.sdl__all:disabled{background:#0a0a0a;cursor:default}
@container (max-width:360px){.sdl__cnt{font-size:12px}.sdl__all{padding:0 10px;font-size:12px}.sdl__card{width:156px}}
@media (prefers-reduced-motion:reduce){.sdl__pt::after{animation:none;opacity:0}.sdl__pt::before{transition:none}}// Shop de look · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.sdl');if(!w)return;
var pts=[].slice.call(w.querySelectorAll('.sdl__pt')),card=w.querySelector('.sdl__card'),nm=w.querySelector('.sdl__nm'),me=w.querySelector('.sdl__me'),pr=w.querySelector('.sdl__pr'),add=w.querySelector('.sdl__add'),cnt=w.querySelector('.sdl__cnt'),all=w.querySelector('.sdl__all'),bar=w.querySelector('.sdl__bar');
var P=[['Bank Lund','3-zits, lichtgrijs, 214 cm breed',1299],['Salontafel Ronde Eik','Massief eiken, doorsnede 90 cm',449],['Vloerlamp Mira','Messing, hoogte 158 cm',189],['Vijgenboom in pot','Ficus lyrata, 120 cm, met pot',79]];
var inB=[false,false,false,false],open=-1;
function eur(n){return '€ '+String(n).replace(/\B(?=(\d{3})+(?!\d))/g,'.');}
function count(){var n=inB.filter(Boolean).length,rest=0;P.forEach(function(p,i){if(!inB[i])rest+=p[2];});cnt.textContent=n+' van 4 in je mandje';
all.disabled=n===4;all.textContent=n===4?'Hele look in je mandje':(n?'Rest toevoegen · '+eur(rest):'Hele look · '+eur(rest));pts.forEach(function(b,i){b.classList.toggle('is-in',inB[i]);});}
function place(i){var wr=w.getBoundingClientRect(),br=pts[i].getBoundingClientRect(),cw=card.offsetWidth,ch=card.offsetHeight,bh=bar.offsetHeight;
var x=br.left-wr.left+br.width/2,y=br.top-wr.top+br.height/2,left=x>wr.width*.5?x-cw-18:x+18;left=Math.max(8,Math.min(wr.width-cw-8,left));
var top=Math.max(8,Math.min(wr.height-bh-ch-8,y-ch/2));card.style.left=left+'px';card.style.top=top+'px';}
function show(i){open=i;var p=P[i];nm.textContent=p[0];me.textContent=p[1];pr.textContent=eur(p[2]);card.setAttribute('aria-label',p[0]);
add.setAttribute('aria-pressed',inB[i]?'true':'false');add.textContent=inB[i]?'In je mandje':'In mandje';card.hidden=false;
pts.forEach(function(b,k){b.setAttribute('aria-expanded',k===i?'true':'false');});place(i);}
function hide(focusBack){if(open<0)return;var i=open;open=-1;card.hidden=true;pts.forEach(function(b){b.setAttribute('aria-expanded','false');});if(focusBack)pts[i].focus();}
pts.forEach(function(b,i){b.addEventListener('click',function(e){e.stopPropagation();if(open===i)hide(false);else show(i);});
b.addEventListener('keydown',function(e){var k=e.key,n=-1;if(k==='ArrowRight'||k==='ArrowDown')n=(i+1)%pts.length;else if(k==='ArrowLeft'||k==='ArrowUp')n=(i-1+pts.length)%pts.length;if(n<0)return;e.preventDefault();pts[n].focus();show(n);});});
add.addEventListener('click',function(){if(open<0)return;inB[open]=!inB[open];show(open);count();});
all.addEventListener('click',function(){inB=[true,true,true,true];count();if(open>=0)show(open);});
w.addEventListener('keydown',function(e){if(e.key==='Escape'&&open>=0){e.preventDefault();hide(true);}});
w.addEventListener('click',function(e){if(open>=0&&!card.contains(e.target)&&!e.target.closest('.sdl__pt'))hide(false);});
if('ResizeObserver' in window)new ResizeObserver(function(){if(open>=0)place(open);}).observe(w);
count();
}
init(document.querySelector('.jouw-container'));
Meer uit componenten
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 →