Iconen die van vorm wisselen New
Four toggle buttons for a customer portal whose icon changes shape: the lock opens, the bell gets a slash, the grid slides into a list and the sound waves turn into a cross. A settings list with real buttons (aria-pressed) and the state in text under the name, so the state never depends on the icon alone. For portal settings, a shop view switch (grid or list) or a media player.
Instellingen in je klantportaal
- Profiel voor collega'sPrivé
- Meldingen per mailMeldingen aan
- Weergave facturenRaster
- Geluid bij een berichtGeluid aan
How to use it
- Paste the HTML where the buttons 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.
<!-- Iconen die van vorm wisselen · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie -->
<div class="jouw-container">
<div class="r7im">
<p class="r7im__h">Instellingen in je klantportaal</p>
<ul class="r7im__rij">
<li class="r7im__cel"><span class="r7im__t">Profiel voor collega's<span class="r7im__s">Privé</span></span><button class="r7im__b" type="button" aria-pressed="true" aria-label="Profiel afschermen voor collega's" data-aan="Privé" data-uit="Gedeeld"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><rect x="5" y="11" width="14" height="10" rx="2"/><path class="r7im__m" data-a="M8 11V7C8 4.8 9.8 3 12 3C14.2 3 16 4.8 16 7V11" data-b="M8 11V5C8 2.8 9.8 1 12 1C14.2 1 16 2.8 16 5V6"/><path d="M12 15.2v2"/></svg></button></li>
<li class="r7im__cel"><span class="r7im__t">Meldingen per mail<span class="r7im__s">Meldingen aan</span></span><button class="r7im__b r7im__bel" type="button" aria-pressed="true" aria-label="Meldingen per mail" data-aan="Meldingen aan" data-uit="Meldingen uit"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><g class="r7im__klok"><path d="M6 16.5V11a6 6 0 0 1 12 0v5.5l1.5 2h-15z"/><path d="M10 21a2 2 0 0 0 4 0"/></g><path class="r7im__gat" pathLength="1" d="M3.5 3.5L20.5 20.5"/><path class="r7im__streep" pathLength="1" d="M3.5 3.5L20.5 20.5"/></svg></button></li>
<li class="r7im__cel"><span class="r7im__t">Weergave facturen<span class="r7im__s">Raster</span></span><button class="r7im__b r7im__vul" type="button" aria-pressed="false" aria-label="Facturen als lijst tonen" data-aan="Lijst" data-uit="Raster"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path class="r7im__m" data-a="M4 4h6.5v6.5h-6.5z" data-b="M4 4h16v2.4h-16z"/><path class="r7im__m" data-a="M13.5 4h6.5v6.5h-6.5z" data-b="M4 8.6h16v2.4h-16z"/><path class="r7im__m" data-a="M4 13.5h6.5v6.5h-6.5z" data-b="M4 13.2h16v2.4h-16z"/><path class="r7im__m" data-a="M13.5 13.5h6.5v6.5h-6.5z" data-b="M4 17.8h16v2.4h-16z"/></svg></button></li>
<li class="r7im__cel"><span class="r7im__t">Geluid bij een bericht<span class="r7im__s">Geluid aan</span></span><button class="r7im__b" type="button" aria-pressed="true" aria-label="Geluid bij een nieuw bericht" data-aan="Geluid aan" data-uit="Geluid uit"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M3.5 9h3.5l5-4v14l-5-4H3.5z"/><path class="r7im__m" data-a="M15.5 9C17 10.5 17 13.5 15.5 15" data-b="M15.5 9C17.5 11 19.5 13 21.5 15"/><path class="r7im__m" data-a="M18.5 6C21.5 9 21.5 15 18.5 18" data-b="M21.5 9C19.5 11 17.5 13 15.5 15"/></svg></button></li>
</ul>
</div>
</div>/* Iconen die van vorm wisselen · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie */
.r7im{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:8px;background:#f4f3f1;color:#0a0a0a;font-family:'Switzer',sans-serif;padding:12px 20px;container-type:size}
.r7im *,.r7im *::before,.r7im *::after{box-sizing:border-box}
.r7im__h{width:100%;max-width:340px;margin:0;font:600 17px/1.2 'Switzer',sans-serif;letter-spacing:-.01em}
.r7im__rij{list-style:none;margin:0;padding:0;width:100%;max-width:340px;display:flex;flex-direction:column}
.r7im__cel{display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0;padding:4px 0;border-top:1px solid rgba(10,10,10,.1)}
.r7im__cel:first-child{border-top:0}
.r7im__t{display:flex;flex-direction:column;gap:1px;font:600 14px/1.2 'Switzer',sans-serif;min-width:0}
.r7im__b{flex:none;width:40px;height:40px;display:grid;place-items:center;margin:0;padding:0;border:1px solid rgba(10,10,10,.18);border-radius:8px;background:#fff;color:#0a0a0a;cursor:pointer;transition:border-color .16s,background-color .16s}
.r7im__b:hover{border-color:#0a0a0a}
.r7im__b:focus-visible{outline:2px solid #F5480F;outline-offset:3px}
.r7im__b:active{transform:translateY(1px)}
.r7im__b svg{width:24px;height:24px;overflow:visible;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.r7im__vul svg{fill:currentColor;stroke:none}
.r7im__b[aria-pressed="true"]{border-color:#F5480F}
.r7im__s{font:400 12px/1.25 'Switzer',sans-serif;color:#5a5853}
.r7im__bel[aria-pressed="true"] .r7im__streep,.r7im__bel[aria-pressed="true"] .r7im__gat{stroke-linecap:butt}
.r7im__streep{stroke-dasharray:1;stroke-dashoffset:1;transition:stroke-dashoffset .3s ease}
.r7im__gat{stroke:#fff;stroke-width:4.5;stroke-dasharray:1;stroke-dashoffset:1;transition:stroke-dashoffset .3s ease}
.r7im__bel[aria-pressed="false"] .r7im__streep,.r7im__bel[aria-pressed="false"] .r7im__gat{stroke-dashoffset:0}
.r7im__bel[aria-pressed="false"] .r7im__klok{opacity:.55}
.r7im__klok{transform-origin:12px 4px;transition:opacity .3s}
.r7im__bel.is-rinkel .r7im__klok{animation:r7im-rinkel .6s ease}
@keyframes r7im-rinkel{0%,100%{transform:rotate(0)}20%{transform:rotate(14deg)}40%{transform:rotate(-11deg)}60%{transform:rotate(7deg)}80%{transform:rotate(-3deg)}}
@container (max-height:230px){.r7im__b{width:32px;height:32px}.r7im__b svg{width:20px;height:20px}.r7im__cel{padding:1px 0}.r7im__t{font-size:13px;gap:0}.r7im__h{font-size:14px}}
@media (prefers-reduced-motion:reduce){.r7im__streep,.r7im__gat{transition:none}.r7im__bel.is-rinkel .r7im__klok{animation:none}}// Iconen die van vorm wisselen · © 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 w=root.querySelector('.r7im');if(!w)return;
var rm=window.matchMedia&&matchMedia('(prefers-reduced-motion: reduce)').matches;
var NUM=/-?\d*\.?\d+/g;
function nums(s){return s.match(NUM).map(Number);}
function zet(el,t){var a=nums(el.getAttribute('data-a')),b=nums(el.getAttribute('data-b')),i=0;
el.setAttribute('d',el.getAttribute('data-a').replace(NUM,function(){var v=a[i]+(b[i]-a[i])*t;i++;return (Math.round(v*100)/100).toString();}));el._t=t;}
function morph(el,naar){
var van=el._t||0;if(el._raf)cancelAnimationFrame(el._raf);
if(rm){zet(el,naar);return;}
var t0=performance.now(),dur=340;
(function stap(nu){var p=Math.min(1,(nu-t0)/dur),e=p<.5?4*p*p*p:1-Math.pow(-2*p+2,3)/2;zet(el,van+(naar-van)*e);if(p<1)el._raf=requestAnimationFrame(stap);})(t0);
}
[].slice.call(w.querySelectorAll('.r7im__b')).forEach(function(b){
var ms=[].slice.call(b.querySelectorAll('.r7im__m')),s=b.parentNode.querySelector('.r7im__s');
var aStand=b.getAttribute('aria-pressed')==='true';
ms.forEach(function(m){zet(m,0);});
b.addEventListener('click',function(){
var aan=b.getAttribute('aria-pressed')!=='true';
b.setAttribute('aria-pressed',aan?'true':'false');
s.textContent=aan?b.getAttribute('data-aan'):b.getAttribute('data-uit');
ms.forEach(function(m){morph(m,aan===aStand?0:1);});
if(b.classList.contains('r7im__bel')&&aan&&!rm){b.classList.remove('is-rinkel');void b.offsetWidth;b.classList.add('is-rinkel');}
});
});
}
init(document.querySelector('.jouw-container'));
More buttons
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 →