Jelly-knop die nawiebelt New
A big button that squashes like jelly when pressed and wobbles on a real spring after release; where you press decides which way it leans. With the keyboard (space or Enter) it wobbles the same way. For the one main action on the site of a hair salon, ice cream parlour or playground. With reduced motion it only changes colour.
Kapsalon Lot, Utrecht
Knippen en föhnen vanaf € 32, ook op zaterdag.
Zaterdag zijn er nog drie plekken vrij.
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.
<!-- Jelly-knop die nawiebelt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie -->
<div class="jouw-container">
<div class="fyj">
<h3 class="fyj__h">Kapsalon Lot, Utrecht</h3>
<p class="fyj__p">Knippen en föhnen vanaf € 32, ook op zaterdag.</p>
<button class="fyj__knop" type="button"><span>Plan je knipbeurt</span></button>
<p class="fyj__st" aria-live="polite">Zaterdag zijn er nog drie plekken vrij.</p>
</div>
</div>/* Jelly-knop die nawiebelt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie */
.fyj{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:16px;background:#f4f3f1;color:#0a0a0a;font-family:'Switzer',sans-serif;text-align:center}
.fyj *{box-sizing:border-box}
.fyj__h{margin:0;font:700 19px/1.15 'Switzer',sans-serif;letter-spacing:-.015em}
.fyj__p{margin:0 0 8px;font:400 13px/1.4 'Switzer',sans-serif;color:#3d3b37}
.fyj__knop{margin:0;padding:18px 30px;border:0;border-radius:8px;background:#F5480F;color:#0a0a0a;font:700 18px/1 'Switzer',sans-serif;cursor:pointer;touch-action:manipulation;user-select:none;-webkit-user-select:none;transform-origin:50% 100%;will-change:transform;box-shadow:inset 0 -5px 0 rgba(10,10,10,.16);transition:background-color .16s}
.fyj__knop:hover{background:#ff5d24}
.fyj__knop:focus-visible{outline:2px solid #0a0a0a;outline-offset:4px}
.fyj__st{margin:6px 0 0;min-height:18px;font:500 13px/1.35 'Switzer',sans-serif;color:#0a0a0a}
@media (prefers-reduced-motion: reduce){.fyj__knop:active{background:#d93d08}}// Jelly-knop die nawiebelt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie
// root = het element waarin de HTML staat
function init(root){
var el=root.querySelector('.fyj');if(!el)return;
var RM=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var btn=el.querySelector('.fyj__knop'),st=el.querySelector('.fyj__st');
var sx=1,sy=1,vx=0,vy=0,k=0,vk=0,tx=1,ty=1,tk=0,raf=0,last=0,down=false,n=0;
function tick(t){var dt=Math.min(.03,(t-last)/1000);last=t;var h=dt/4;for(var i=0;i<4;i++){vx+=((tx-sx)*420-vx*8)*h;vy+=((ty-sy)*420-vy*8)*h;vk+=((tk-k)*260-vk*7)*h;sx+=vx*h;sy+=vy*h;k+=vk*h;}
btn.style.transform='scale('+sx.toFixed(4)+','+sy.toFixed(4)+') skewX('+k.toFixed(3)+'deg)';
var e=Math.abs(sx-tx)+Math.abs(sy-ty)+Math.abs(vx)*.02+Math.abs(vy)*.02+Math.abs(k-tk)*.05+Math.abs(vk)*.01;
if(e<.0015&&!down){sx=tx;sy=ty;k=tk;vx=vy=vk=0;btn.style.transform='';raf=0;return;}raf=requestAnimationFrame(tick);}
function kick(){if(RM||raf)return;last=performance.now();raf=requestAnimationFrame(tick);}
function druk(off){down=true;tx=1.12;ty=.84;tk=off*8;kick();}
function los(){if(!down)return;down=false;tx=1;ty=1;tk=0;vy-=1.2;kick();}
btn.addEventListener('pointerdown',function(e){if(e.button>0)return;var r=btn.getBoundingClientRect();druk(Math.max(-1,Math.min(1,((e.clientX-r.left)/r.width-.5)*2)));});
btn.addEventListener('pointerup',los);btn.addEventListener('pointercancel',los);btn.addEventListener('pointerleave',los);
btn.addEventListener('pointerenter',function(e){if(e.pointerType==='mouse'&&!down){vy+=1.1;vx-=.7;kick();}});
btn.addEventListener('keydown',function(e){if((e.key===' '||e.key==='Enter')&&!e.repeat)druk(0);});
btn.addEventListener('keyup',function(e){if(e.key===' '||e.key==='Enter')los();});
btn.addEventListener('blur',los);
var T=['Agenda geopend: zaterdag 26 oktober, nog 14:30, 15:15 en 16:00 vrij.','Je kiest zo een tijd en een kapper. Annuleren kan tot een dag vooraf.'];
btn.addEventListener('click',function(){st.textContent=T[n++%T.length];});
}
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 →