Avatar Stack
介绍
重叠的成员头像,悬停时依次展开并显示名字气泡,末尾 +N 计数。头像是首字母 + 渐变,无需图片。
纯 HTML、CSS 与少量原生 JS,没有框架依赖。复制提示词交给 Claude Code、Cursor、Trae 或 Codex,模型会把 Avatar Stack 加进你的项目并换成你的配色。
适用场景
仪表盘、数据表格、图表卡片、对比表和状态面板。
安装
订阅 Builder 后,用 8pt CLI 装进项目,或在已接入 8pt MCP 的编辑器里直接调用。
$ npm i -g @8pt-dev/cli && 8pt add avatar-stack
mcp › 使用 8pt MCP 调用 get_component("avatar-stack")
代码
Avatar Stack 的源码,动效只用 transform 与 opacity,并尊重减少动态效果设置。
<div class="x-av">
<div class="x-av__row">
<button type="button" style="--c1:#7b6bff;--c2:#00c2ff" data-n="Ava Chen">AC</button>
<button type="button" style="--c1:#ff7a59;--c2:#ffcc4d" data-n="Leo Park">LP</button>
<button type="button" style="--c1:#21c58e;--c2:#7ef0c4" data-n="Mia Rossi">MR</button>
<button type="button" style="--c1:#e05bff;--c2:#ff8ad8" data-n="Noah Kim">NK</button>
<button type="button" style="--c1:#4d74ff;--c2:#8fb0ff" data-n="Zoe Liu">ZL</button>
<span class="x-av__more">+12</span>
</div>
<p class="x-av__cap">17 位成员正在编辑</p>
</div>.x-av{display:grid;justify-items:center;gap:14px;color:var(--d-fg,#fff)}
.x-av__row{display:flex;align-items:center;padding:6px 10px}
.x-av__row>*{position:relative;flex:none;display:grid;place-items:center;width:48px;height:48px;margin-left:-14px;border-radius:50%;border:3px solid var(--d-bg,#09090d);font:700 13px/1 var(--d-font,system-ui,sans-serif);transition:transform .4s cubic-bezier(.3,1.3,.5,1)}
.x-av__row>*:first-child{margin-left:0}
.x-av__row button{padding:0;color:#fff;background:linear-gradient(135deg,var(--c1),var(--c2));cursor:pointer}
.x-av__more{background:var(--d-card,#14141c);color:var(--d-muted,#9b9ba8);font-size:12px}
.x-av__row button::after{content:attr(data-n);position:absolute;left:50%;bottom:calc(100% + 8px);padding:5px 8px;border-radius:7px;background:var(--d-fg,#fff);color:var(--d-bg,#000);font:600 11px/1 var(--d-font,system-ui,sans-serif);white-space:nowrap;opacity:0;transform:translate(-50%,4px);transition:opacity .2s,transform .2s;pointer-events:none}
.x-av__row button:hover::after,.x-av__row button:focus-visible::after{opacity:1;transform:translate(-50%,0)}
.x-av__row:hover>*,.x-av__row.open>*{transform:translateX(calc(var(--i) * 10px))}
.x-av__row>*:hover{z-index:2}
.x-av__row button:hover{transform:translateX(calc(var(--i) * 10px)) translateY(-4px)}
.x-av__cap{margin:0;display:flex;align-items:center;gap:8px;font:12.5px/1 var(--d-font,system-ui,sans-serif);color:var(--d-muted,#9b9ba8)}
…const init = (root) => {
const row = root.querySelector('.x-av__row');
[...row.children].forEach((el, i) => el.style.setProperty('--i', i));
// breathe open/closed once so the preview shows the interaction
if (matchMedia('(prefers-reduced-motion: reduce)').matches) return;
let t1 = setTimeout(() => row.classList.add('open'), 900), t2 = setTimeout(() => row.classList.remove('open'), 2400);
return () => { clearTimeout(t1); clearTimeout(t2); };
};订阅 Builder 查看完整源码。查看价格