Hovercard teamlid + uitleg New
Names in running text and an avatar row open a card with a contact person or a glossary explanation. Hover opens with delay, click or Enter pins it; light dismiss and Esc via popover="auto", enter/exit animation with @starting-style. Anchor positioning with a JS positioning fallback.
Jouw dossier · badkamer Kerkstraat 8, Amersfoort
Je project wordt begeleid door , projectleider, en van calculatie. In de offerte staat een voor de tegels.
Start bij jou op wo 21 okt
Joost legt de vloer en wanden. Vragen over de planning lopen via Sanne.
Een gereserveerd bedrag, hier € 1.200, voor tegels die je nog zelf uitkiest. Kies je duurder, dan betaal je het verschil. Kies je goedkoper, dan krijg je het terug.
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.
<!-- Hovercard teamlid + uitleg · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="hcp">
<p class="hcp__eyebrow">Jouw dossier · badkamer Kerkstraat 8, Amersfoort</p>
<p class="hcp__txt">Je project wordt begeleid door <button class="hcp__name" type="button" popovertarget="hcp-sanne">Sanne de Wit</button>, projectleider, en <button class="hcp__name" type="button" popovertarget="hcp-mehmet">Mehmet Yıldız</button> van calculatie. In de offerte staat een <button class="hcp__name hcp__name--term" type="button" popovertarget="hcp-stel">stelpost</button> voor de tegels.</p>
<div class="hcp__team"><span class="hcp__lbl">Team</span>
<button class="hcp__av hcp__av--a" type="button" popovertarget="hcp-sanne" aria-label="Sanne de Wit">SW</button>
<button class="hcp__av hcp__av--b" type="button" popovertarget="hcp-mehmet" aria-label="Mehmet Yıldız">MY</button>
<button class="hcp__av hcp__av--c" type="button" popovertarget="hcp-joost" aria-label="Joost Bakker">JB</button>
</div>
<div id="hcp-sanne" class="hcp__card" popover="auto" role="dialog" aria-label="Sanne de Wit">
<div class="hcp__head"><span class="hcp__pic hcp__av--a" aria-hidden="true">SW</span><div><strong>Sanne de Wit</strong><span>Projectleider · Amersfoort</span></div></div>
<p class="hcp__stat"><span class="hcp__dot" aria-hidden="true"></span>Bereikbaar tot 17:00</p>
<dl class="hcp__meta"><div><dt>Tel</dt><dd><a href="tel:+31331234567">033 123 4567</a></dd></div><div><dt>Mail</dt><dd><a href="mailto:sanne@voorbeeld.nl">sanne@voorbeeld.nl</a></dd></div></dl>
<a class="hcp__cta" href="#belafspraak">Plan een belafspraak</a>
</div>
<div id="hcp-mehmet" class="hcp__card" popover="auto" role="dialog" aria-label="Mehmet Yıldız">
<div class="hcp__head"><span class="hcp__pic hcp__av--b" aria-hidden="true">MY</span><div><strong>Mehmet Yıldız</strong><span>Calculator · ma t/m do</span></div></div>
<p class="hcp__stat"><span class="hcp__dot hcp__dot--busy" aria-hidden="true"></span>In overleg, terug om 14:30</p>
<dl class="hcp__meta"><div><dt>Tel</dt><dd><a href="tel:+31331234568">033 123 4568</a></dd></div><div><dt>Mail</dt><dd><a href="mailto:mehmet@voorbeeld.nl">mehmet@voorbeeld.nl</a></dd></div></dl>
<a class="hcp__cta" href="#offerte">Vraag over je offerte</a>
</div>
<div id="hcp-joost" class="hcp__card" popover="auto" role="dialog" aria-label="Joost Bakker">
<div class="hcp__head"><span class="hcp__pic hcp__av--c" aria-hidden="true">JB</span><div><strong>Joost Bakker</strong><span>Tegelzetter · 14 jaar in dienst</span></div></div>
<p class="hcp__stat"><span class="hcp__dot hcp__dot--off" aria-hidden="true"></span>Start bij jou op wo 21 okt</p>
<p class="hcp__note">Joost legt de vloer en wanden. Vragen over de planning lopen via Sanne.</p>
</div>
<div id="hcp-stel" class="hcp__card hcp__card--term" popover="auto" role="dialog" aria-label="Wat is een stelpost?">
<span class="hcp__kick">Begrip</span><strong>Stelpost</strong>
<p class="hcp__note">Een gereserveerd bedrag, hier € 1.200, voor tegels die je nog zelf uitkiest. Kies je duurder, dan betaal je het verschil. Kies je goedkoper, dan krijg je het terug.</p>
</div>
</div>
</div>/* Hovercard teamlid + uitleg · NedDev · eigen werk. */
.hcp{--ink:#0a0a0a;--pd:#b83a0b;position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;gap:12px;padding:18px 22px;font-family:'Switzer',system-ui,sans-serif;color:var(--ink)}
.hcp__eyebrow{margin:0;font:600 10px/1.3 'JetBrains Mono',monospace;letter-spacing:.12em;text-transform:uppercase;color:#5b5b5b}
.hcp__txt{margin:0;font-size:15px;line-height:1.55;max-width:44ch}
.hcp__name{font:inherit;font-weight:600;color:inherit;background:none;border:0;padding:0;cursor:pointer;text-decoration:underline;text-decoration-color:#F5480F;text-decoration-thickness:2px;text-underline-offset:3px;transition:color .15s}
.hcp__name:hover{color:var(--pd)}
.hcp__name--term{text-decoration-style:dotted;text-decoration-color:var(--ink);font-weight:500}
.hcp__name:focus-visible,.hcp__av:focus-visible,.hcp__card a:focus-visible{outline:2px solid var(--pd);outline-offset:2px;border-radius:2px}
.hcp__team{display:flex;align-items:center;gap:0}
.hcp__lbl{font:600 10px/1 'JetBrains Mono',monospace;letter-spacing:.12em;text-transform:uppercase;color:#5b5b5b;margin-right:10px}
.hcp__av{width:34px;height:34px;border-radius:50%;border:2px solid #f4f3f1;margin-left:-6px;font:700 11px/1 'JetBrains Mono',monospace;cursor:pointer;display:grid;place-items:center;padding:0;transition:transform .15s}
.hcp__av:first-of-type{margin-left:0}
.hcp__av:hover{transform:translateY(-2px)}
.hcp__av--a{background:#0a0a0a;color:#fff}.hcp__av--b{background:#F5480F;color:#0a0a0a}.hcp__av--c{background:#d9d5ce;color:#0a0a0a}
.hcp__card{position:fixed;inset:auto;margin:0;width:236px;padding:14px;border:1px solid rgba(10,10,10,.14);border-radius:6px;background:#fff;color:var(--ink);font-family:'Switzer',system-ui,sans-serif;box-shadow:0 14px 32px rgba(10,10,10,.14);opacity:0;translate:0 6px;transition:opacity .18s ease,translate .18s ease,overlay .18s allow-discrete,display .18s allow-discrete}
.hcp__card:popover-open{opacity:1;translate:0 0}
@starting-style{.hcp__card:popover-open{opacity:0;translate:0 6px}}
@supports (anchor-name:--a){.hcp__card{position-area:bottom;margin-top:8px;position-try-fallbacks:flip-block}}
.hcp__head{display:flex;gap:10px;align-items:center}
.hcp__pic{width:40px;height:40px;border-radius:4px;display:grid;place-items:center;font:700 12px/1 'JetBrains Mono',monospace;flex:none}
.hcp__head strong{display:block;font-size:14px}
.hcp__head div span{font-size:12px;color:#5b5b5b}
.hcp__stat{display:flex;align-items:center;gap:7px;margin:10px 0 0;font-size:12px}
.hcp__dot{width:8px;height:8px;border-radius:50%;background:#16833f;flex:none}
.hcp__dot--busy{background:#c27c00}.hcp__dot--off{background:#8a8a8a}
.hcp__meta{margin:10px 0 0;display:grid;gap:4px;font-size:12px}
.hcp__meta div{display:flex;gap:8px}
.hcp__meta dt{width:34px;font:600 9.5px/1.7 'JetBrains Mono',monospace;letter-spacing:.08em;text-transform:uppercase;color:#5b5b5b}
.hcp__meta dd{margin:0}
.hcp__meta a{color:var(--ink)}
.hcp__cta{display:block;margin-top:12px;padding:8px 10px;border-radius:4px;background:var(--ink);color:#fff;font-size:12px;font-weight:600;text-align:center;text-decoration:none;transition:background .15s}
.hcp__cta:hover{background:#2a2a2a}
.hcp__note{margin:8px 0 0;font-size:12.5px;line-height:1.5;color:#2b2b2b}
.hcp__kick{display:block;font:600 9.5px/1 'JetBrains Mono',monospace;letter-spacing:.12em;text-transform:uppercase;color:var(--pd);margin-bottom:4px}
.hcp__card--term strong{font-size:15px}
@media (max-width:420px){.hcp{padding:14px 16px}.hcp__txt{font-size:13.5px}}
@media (prefers-reduced-motion:reduce){.hcp__card{transition:none}}// Hovercard teamlid + uitleg · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.hcp');if(!w)return;
var U='-'+Math.random().toString(36).slice(2,7);
w.querySelectorAll('[id]').forEach(function(el){var o=el.id,n=o+U;el.id=n;w.querySelectorAll('[popovertarget="'+o+'"]').forEach(function(x){x.setAttribute('popovertarget',n);});});
if(typeof HTMLElement.prototype.showPopover!=='function')return;
var hasAnchor=!!(window.CSS&&CSS.supports('anchor-name: --a'));var k=0,oT=0,cT=0,cur=null,mode=null;
function card(t){return document.getElementById(t.getAttribute('popovertarget'));}
function place(t,c){if(hasAnchor){c.style.positionAnchor=t.style.anchorName;return;}
var r=t.getBoundingClientRect(),bw=c.offsetWidth,bh=c.offsetHeight,x=r.left+r.width/2-bw/2,y=r.bottom+8;if(y+bh>innerHeight-4)y=r.top-bh-8;
c.style.left=Math.max(4,Math.min(innerWidth-bw-4,x))+'px';c.style.top=Math.max(4,y)+'px';}
function open(t,how){var c=card(t);if(!c)return;if(hasAnchor)c.style.positionAnchor=t.style.anchorName;if(!c.matches(':popover-open'))c.showPopover({source:t});place(t,c);cur=t;mode=how;}
function close(c){if(c&&c.matches(':popover-open'))c.hidePopover();}
w.querySelectorAll('[popovertarget]').forEach(function(t){if(hasAnchor)t.style.anchorName='--hcp'+U.slice(1)+(k++);var c=card(t);
t.addEventListener('pointerenter',function(e){if(e.pointerType!=='mouse')return;clearTimeout(cT);clearTimeout(oT);oT=setTimeout(function(){open(t,'hover');},350);});
t.addEventListener('pointerleave',function(){clearTimeout(oT);if(mode!=='hover')return;cT=setTimeout(function(){close(c);},260);});
t.addEventListener('click',function(e){var open_=c.matches(':popover-open');
if(open_&&(mode==='hover'||cur!==t)){e.preventDefault();open(t,'click');return;}
if(!open_){e.preventDefault();open(t,'click');}});});
w.querySelectorAll('.hcp__card').forEach(function(c){
c.addEventListener('pointerenter',function(){clearTimeout(cT);});
c.addEventListener('pointerleave',function(){if(mode==='hover')cT=setTimeout(function(){close(c);},260);});
c.addEventListener('toggle',function(e){if(e.newState==='closed'){if(cur&&card(cur)===c){cur=null;mode=null;}}});});
if(!hasAnchor)window.addEventListener('scroll',function(){w.querySelectorAll('.hcp__card').forEach(close);},true);
}
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 →