Verbindingslijnen (zo werkt het) New
A "how it works" diagram: three channels on the left, your system in the middle, two outcomes on the right, joined by SVG curves with a calm orange pulse (stroke-dashoffset). Lines are computed from real positions (ResizeObserver), hovering a block highlights its lines and a pause button stops the motion (WCAG 2.2.2). Static with reduced motion.
Elke aanvraag op één plek
- Websiteformulier
- Telefoon
Uw CRMlead binnen 2 min verwerkt
- Offerte als pdf
- Agenda monteur
3 kanalen in, 2 acties uit · voorbeeld voor een installateur
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.
<!-- Verbindingslijnen (zo werkt het) · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="vbl"><div class="vbl__hd"><p class="vbl__t">Elke aanvraag op één plek</p><button type="button" class="vbl__pz"><svg viewBox="0 0 12 12" aria-hidden="true"><path class="vbl__ip" d="M3 2h2v8H3zM7 2h2v8H7z"/><path class="vbl__ipl" d="M3 2l7 4-7 4z"/></svg><span>Pauzeer</span></button></div>
<div class="vbl__map"><svg class="vbl__svg" aria-hidden="true"></svg>
<ul class="vbl__col" aria-label="Kanalen"><li class="vbl__n" data-n="a"><span class="vbl__i"><svg viewBox="0 0 20 20"><rect x="3" y="4" width="14" height="12" rx="1.5"/><path d="M6 8h8M6 11h5"/></svg></span>Websiteformulier</li><li class="vbl__n" data-n="b"><span class="vbl__i"><svg viewBox="0 0 20 20"><path d="M4 15.5 5 12.5A6.5 6.5 0 1 1 7.5 15z"/></svg></span>WhatsApp</li><li class="vbl__n" data-n="c"><span class="vbl__i"><svg viewBox="0 0 20 20"><path d="M5 3.5h3l1.2 3.3-1.7 1.2a8 8 0 0 0 4.5 4.5l1.2-1.7 3.3 1.2v3a1.3 1.3 0 0 1-1.3 1.3A12.7 12.7 0 0 1 3.7 4.8 1.3 1.3 0 0 1 5 3.5z"/></svg></span>Telefoon</li></ul>
<div class="vbl__hub vbl__n" data-n="h"><span class="vbl__hk">Uw CRM</span><span class="vbl__hs">lead binnen 2 min verwerkt</span></div>
<ul class="vbl__col" aria-label="Uitkomsten"><li class="vbl__n" data-n="x"><span class="vbl__i"><svg viewBox="0 0 20 20"><path d="M5.5 2.5h6l3 3v12h-9z"/><path d="M8 11l1.6 1.6L13 9"/></svg></span>Offerte als pdf</li><li class="vbl__n" data-n="y"><span class="vbl__i"><svg viewBox="0 0 20 20"><rect x="3" y="4.5" width="14" height="12.5" rx="1.5"/><path d="M3 8.5h14M7 2.5v3M13 2.5v3"/></svg></span>Agenda monteur</li></ul></div>
<p class="vbl__f">3 kanalen in, 2 acties uit · voorbeeld voor een installateur</p></div>
</div>/* Verbindingslijnen (zo werkt het) · NedDev · eigen werk. */
.vbl{position:absolute;inset:0;box-sizing:border-box;padding:14px 16px 10px;background:#f4f3f1;color:#0a0a0a;font-family:'Switzer',system-ui,sans-serif;display:flex;flex-direction:column;gap:8px}
.vbl__hd{display:flex;justify-content:space-between;align-items:center;gap:8px}
.vbl__t{margin:0;font-size:15px;font-weight:650}
.vbl__pz{display:inline-flex;align-items:center;gap:5px;font:600 10.5px 'Switzer',system-ui,sans-serif;color:#0a0a0a;background:#fff;border:1px solid rgba(10,10,10,.18);border-radius:999px;padding:4px 9px;cursor:pointer;transition:border-color .15s}
.vbl__pz:hover{border-color:#0a0a0a}.vbl__pz:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.vbl__pz svg{width:10px;height:10px;fill:currentColor}.vbl__ipl{display:none}
.vbl.is-paused .vbl__ip{display:none}.vbl.is-paused .vbl__ipl{display:inline}
.vbl__map{position:relative;flex:1;min-height:0;display:grid;grid-template-columns:1fr .85fr 1fr;align-items:center;gap:0 30px}
.vbl__svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.vbl__col{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px;position:relative;z-index:1}
.vbl__n{display:flex;align-items:center;gap:7px;background:#fff;border:1px solid rgba(10,10,10,.14);border-radius:4px;padding:6px 8px;font-size:11.5px;font-weight:550;line-height:1.2;transition:border-color .18s}
.vbl__n:hover{border-color:#0a0a0a}
.vbl__i{flex:none;width:22px;height:22px;border-radius:3px;background:#f4f3f1;display:grid;place-items:center}
.vbl__i svg{width:15px;height:15px;fill:none;stroke:#0a0a0a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.vbl__hub{position:relative;z-index:1;flex-direction:column;align-items:flex-start;gap:3px;background:#0a0a0a;color:#fff;border-color:#0a0a0a;padding:12px 10px;border-left:3px solid #F5480F}
.vbl__hub:hover{border-color:#0a0a0a;border-left-color:#F5480F}
.vbl__hk{font-size:14px;font-weight:700}.vbl__hs{font:500 9.5px/1.3 'JetBrains Mono',monospace;color:#cfcdc9}
.vbl__ln{fill:none;stroke:rgba(10,10,10,.2);stroke-width:1.5;transition:stroke .2s}
.vbl__ps{fill:none;stroke:#F5480F;stroke-width:2;stroke-linecap:round;stroke-dasharray:12 88;animation:vbl-run 2.6s linear infinite}
.vbl__ln.is-hl{stroke:#F5480F}
.vbl.is-paused .vbl__ps{animation-play-state:paused}
@keyframes vbl-run{from{stroke-dashoffset:100}to{stroke-dashoffset:0}}
.vbl__f{margin:0;font:500 9.5px 'JetBrains Mono',monospace;color:#6b6a66}
@media(max-width:420px){.vbl{padding:10px 10px 8px}.vbl__map{gap:0 16px;grid-template-columns:1fr .8fr 1fr}.vbl__n{font-size:10px;padding:5px 6px;gap:5px}.vbl__i{width:18px;height:18px}.vbl__i svg{width:12px;height:12px}.vbl__hk{font-size:12px}.vbl__col{gap:6px}.vbl__f{display:none}}
@media(prefers-reduced-motion:reduce){.vbl__ps{display:none}.vbl__pz{display:none}}// Verbindingslijnen (zo werkt het) · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.vbl');if(!w)return;var map=w.querySelector('.vbl__map'),svg=w.querySelector('.vbl__svg'),NS='http://www.w3.org/2000/svg';
var links=[['a','h'],['b','h'],['c','h'],['h','x'],['h','y']],node={};w.querySelectorAll('.vbl__n').forEach(function(n){node[n.dataset.n]=n;});
function draw(){var mr=map.getBoundingClientRect();if(!mr.width)return;svg.setAttribute('viewBox','0 0 '+mr.width+' '+mr.height);svg.innerHTML='';
links.forEach(function(l,i){var a=node[l[0]].getBoundingClientRect(),b=node[l[1]].getBoundingClientRect();var sx=a.right-mr.left,sy=a.top+a.height/2-mr.top,ex=b.left-mr.left,ey=b.top+b.height/2-mr.top;
if(l[0]==='h'){sy=sy+(i===3?-8:8);}else{ey=ey+(i-1)*8;}var dx=(ex-sx)*.55,d='M'+sx+','+sy+'C'+(sx+dx)+','+sy+' '+(ex-dx)+','+ey+' '+ex+','+ey;
var p=document.createElementNS(NS,'path');p.setAttribute('d',d);p.setAttribute('class','vbl__ln');p.dataset.a=l[0];p.dataset.b=l[1];svg.appendChild(p);
var q=document.createElementNS(NS,'path');q.setAttribute('d',d);q.setAttribute('class','vbl__ps');q.setAttribute('pathLength','100');q.style.animationDelay=(l[0]==='h'?1.3+(i-3)*.4:i*.45)+'s';svg.appendChild(q);});}
draw();if('ResizeObserver' in window)new ResizeObserver(draw).observe(map);
Object.keys(node).forEach(function(k){node[k].addEventListener('pointerenter',function(){svg.querySelectorAll('.vbl__ln').forEach(function(p){p.classList.toggle('is-hl',p.dataset.a===k||p.dataset.b===k);});});node[k].addEventListener('pointerleave',function(){svg.querySelectorAll('.is-hl').forEach(function(p){p.classList.remove('is-hl');});});});
var pz=w.querySelector('.vbl__pz');pz.addEventListener('click',function(){var on=!w.classList.contains('is-paused');w.classList.toggle('is-paused',on);pz.querySelector('span').textContent=on?'Speel af':'Pauzeer';});
}
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 →