Beeld-hover · zoom, meeschuiven, onthullen New
Three hover states for framed photos: a slow zoom, a pan where a slightly enlarged photo follows the cursor, and a reveal where the colour photo slides over a grey version from the left. Frame and size stay put, only the image moves. For collections, projects or a showroom; with reduced motion there is no zoom and no pan.
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.
<!-- Beeld-hover · zoom, meeschuiven, onthullen · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="hbz">
<figure class="hbz__f"><a class="hbz__fr hbz__fr--zoom" href="#hv-beeld-zoom-set"><img src="https://neddev.com/lab-media/hv-beeld-zoom-set-1.webp" alt="Eiken eettafel met zes stoelen" width="900" height="491" loading="lazy"></a><figcaption class="hbz__c">Zoom</figcaption></figure>
<figure class="hbz__f"><a class="hbz__fr hbz__fr--pan" href="#hv-beeld-zoom-set"><img src="https://neddev.com/lab-media/hv-beeld-zoom-set-3.webp" alt="Showroom in een oud pakhuis in Amersfoort" width="900" height="502" loading="lazy"></a><figcaption class="hbz__c">Meeschuiven</figcaption></figure>
<figure class="hbz__f"><a class="hbz__fr hbz__fr--rev" href="#hv-beeld-zoom-set"><img class="hbz__grey" src="https://neddev.com/lab-media/hv-beeld-zoom-set-2.webp" alt="" width="900" height="491" loading="lazy"><img class="hbz__col" src="https://neddev.com/lab-media/hv-beeld-zoom-set-2.webp" alt="Keramieken tafellamp met linnen kap" width="900" height="491" loading="lazy"></a><figcaption class="hbz__c">Onthullen</figcaption></figure>
</div>
</div>/* Beeld-hover · zoom, meeschuiven, onthullen · NedDev · eigen werk. */
.hbz{position:absolute;inset:0;display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);grid-template-rows:minmax(0,1fr) minmax(0,1fr);gap:10px 14px;padding:14px 16px 10px;background:#f4f3f1;font-family:'Switzer',sans-serif;color:#0a0a0a;container-type:size;text-align:left}
.hbz *,.hbz *::before,.hbz *::after{box-sizing:border-box}
.hbz__f{margin:0;display:flex;flex-direction:column;gap:5px;min-height:0;min-width:0}
.hbz__f:first-child{grid-row:1/3}
.hbz__fr{position:relative;display:block;flex:1;min-height:0;overflow:hidden;border-radius:4px;background:#d9d6d0;outline:none}
.hbz__fr:focus-visible{box-shadow:0 0 0 2px #f4f3f1,0 0 0 4px #F5480F}
.hbz__fr img{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:cover}
.hbz__c{font:500 12px/1.2 'Switzer',sans-serif;color:#55524d}
.hbz__fr--zoom img{transition:transform .7s cubic-bezier(.2,.7,.3,1)}
.hbz__fr--zoom:hover img,.hbz__fr--zoom:focus-visible img{transform:scale(1.09)}
.hbz__fr--pan img{transform:translate(var(--px,0%),var(--py,0%)) scale(1.28);transition:transform .5s cubic-bezier(.2,.7,.3,1)}
.hbz__fr--pan:not(:hover):not(:focus-visible) img{transform:scale(1.12)}
.hbz__grey{filter:grayscale(1) contrast(.9) brightness(1.05)}
.hbz__col{clip-path:inset(0 100% 0 0);transition:clip-path .55s cubic-bezier(.65,0,.35,1)}
.hbz__fr--rev:hover .hbz__col,.hbz__fr--rev:focus-visible .hbz__col{clip-path:inset(0 0 0 0)}
@container (max-height:230px){.hbz{padding:10px 12px 8px;gap:8px 10px}}
@media (prefers-reduced-motion:reduce){.hbz__fr img{transition:none}.hbz__fr--zoom:hover img,.hbz__fr--zoom:focus-visible img,.hbz__fr--pan img,.hbz__fr--pan:not(:hover):not(:focus-visible) img{transform:none}.hbz__col{transition:opacity .2s;clip-path:none;opacity:0}.hbz__fr--rev:hover .hbz__col,.hbz__fr--rev:focus-visible .hbz__col{opacity:1}}// Beeld-hover · zoom, meeschuiven, onthullen · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var p=root.querySelector('.hbz__fr--pan');if(!p)return;
var raf=0,ex=0,ey=0;
p.addEventListener('pointermove',function(e){ex=e.clientX;ey=e.clientY;if(raf)return;raf=requestAnimationFrame(function(){raf=0;var r=p.getBoundingClientRect();var nx=(ex-r.left)/r.width-.5,ny=(ey-r.top)/r.height-.5;p.style.setProperty('--px',(-nx*20).toFixed(2)+'%');p.style.setProperty('--py',(-ny*20).toFixed(2)+'%');});});
p.addEventListener('pointerleave',function(){p.style.setProperty('--px','0%');p.style.setProperty('--py','0%');});
}
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 →

