Kader opent tot volle breedte New
A photo starts inside a framed inset and opens to full width as you scroll, using clip-path: inset() and a gentle zoom-out. Uses a scroll-driven animation (scroll-timeline on its own scroll container, @property for progress); without support a small scroll script takes over. With reduced motion the image is shown fully open.
Wonen aan de Vecht
Een villa van baksteen en glas in Maarssen, ontworpen door Studio Kade.

Villa Zuilen, 240 m², opgeleverd in juni 2026
Daarna loopt de pagina door met plattegronden, materialen en de bouwtijd.
How to use it
- Paste the HTML where the scroll effects 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.
<!-- Kader opent tot volle breedte · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="vpk">
<div class="vpk__sc" tabindex="0" aria-label="Voorbeeld: villa aan de Vecht, scroll om het kader te openen">
<div class="vpk__track"><div class="vpk__pin">
<div class="vpk__intro"><h3 class="vpk__h">Wonen aan de Vecht</h3><p class="vpk__p">Een villa van baksteen en glas in Maarssen, ontworpen door Studio Kade.</p></div>
<div class="vpk__frame"><img class="vpk__img" src="https://neddev.com/lab-media/viewport-kader-1.webp" alt="Bakstenen villa met grote ramen aan het water" loading="lazy"></div>
<p class="vpk__cap">Villa Zuilen, 240 m², opgeleverd in juni 2026</p>
</div></div>
<div class="vpk__na"><p>Daarna loopt de pagina door met plattegronden, materialen en de bouwtijd.</p></div>
</div>
</div>
</div>/* Kader opent tot volle breedte · NedDev · eigen werk. */
@property --vpk-p{syntax:'<number>';inherits:true;initial-value:0}
.vpk{position:absolute;inset:0;background:#fff;color:#0a0a0a;font-family:'Switzer',sans-serif;container-type:size;text-align:left}
.vpk__sc{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scroll-timeline:--vpk-tl y}
.vpk__sc:focus-visible{outline:2px solid #F5480F;outline-offset:-2px}
.vpk__track{height:260cqh;position:relative}
.vpk__pin{position:sticky;top:0;height:100cqh;overflow:hidden;--vpk-p:0}
@supports (animation-timeline: scroll()){.vpk__pin{animation:vpk-open linear both;animation-timeline:--vpk-tl;animation-range:0% 60%}}
@keyframes vpk-open{to{--vpk-p:1}}
.vpk__intro{position:absolute;left:16px;right:16px;top:12px;opacity:calc(1 - var(--vpk-p)*2.4)}
.vpk__h{margin:0;font:700 clamp(17px,5.6cqi,34px)/1.05 'Switzer',sans-serif;letter-spacing:-.025em}
.vpk__p{margin:4px 0 0;font:400 clamp(11px,3cqi,15px)/1.4 'Switzer',sans-serif;color:#4a4845;max-width:34em}
.vpk__frame{position:absolute;inset:0;overflow:hidden;clip-path:inset(calc((1 - var(--vpk-p))*40%) calc((1 - var(--vpk-p))*16px) calc((1 - var(--vpk-p))*16px) round calc((1 - var(--vpk-p))*4px))}
.vpk__img{display:block;width:100%;height:100%;object-fit:cover;transform:scale(calc(1.14 - .14*var(--vpk-p)))}
.vpk__cap{position:absolute;left:16px;bottom:14px;margin:0;color:#fff;font:600 clamp(13px,3.6cqi,18px)/1.2 'Switzer',sans-serif;text-shadow:0 1px 10px rgba(0,0,0,.6);opacity:calc((var(--vpk-p) - .75)*4)}
.vpk__na{padding:18px 16px 28px;font:400 14px/1.5 'Switzer',sans-serif;color:#4a4845}
.vpk__na p{margin:0}
@media (prefers-reduced-motion:reduce){.vpk__pin{animation:none!important;--vpk-p:1}.vpk__track{height:auto}.vpk__pin{position:relative}.vpk__intro{display:none}}// Kader opent tot volle breedte · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.vpk');if(!w)return;
var sc=w.querySelector('.vpk__sc'),pin=w.querySelector('.vpk__pin'),tr=w.querySelector('.vpk__track');
var rm=matchMedia('(prefers-reduced-motion: reduce)').matches;if(rm)return;
if(!(window.CSS&&CSS.supports&&CSS.supports('animation-timeline: scroll()'))){var tick=false;
function upd(){tick=false;var max=sc.scrollHeight-sc.clientHeight;var p=max>0?Math.min(1,sc.scrollTop/(max*.6)):0;pin.style.setProperty('--vpk-p',p.toFixed(4));}
sc.addEventListener('scroll',function(){if(!tick){tick=true;requestAnimationFrame(upd);}},{passive:true});upd();}
var on=true,t0=0;['wheel','touchstart','pointerdown','keydown','focusin'].forEach(function(ev){w.addEventListener(ev,function(){on=false;},{passive:true});});
function drift(now){if(!on)return;if(!t0)t0=now;var m=tr.offsetHeight-sc.clientHeight;sc.scrollTop=m*(.5-.5*Math.cos((now-t0)/1000*.4));requestAnimationFrame(drift);}
setTimeout(function(){if(on)requestAnimationFrame(drift);},900);
}
init(document.querySelector('.jouw-container'));
More scroll effects
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 →