Avatar group

아바타 그룹

Several users overlapped into a tight horizontal stack, with whatever doesn’t fit rolled into a "+2" count.

Also known as: Stacked avatarsFacepile
···
html
<div class="agw">
  <div class="aglist" id="aglist" role="group" aria-label="참여자 5명">
    <span class="agitem" style="background:#5b5bf7" title="정경훈">정</span>
    <span class="agitem" style="background:#f25c8a" title="김서연">김</span>
    <span class="agitem" style="background:#18c29c" title="박도윤">박</span>
    <button class="agmore" aria-haspopup="dialog" aria-label="나머지 2명 더 보기">+2</button>
  </div>
  <div class="agcallout" id="agcallout"></div>
</div>
css
.agw{position:absolute;inset:0;display:grid;place-items:center;gap:14px}
.aglist{display:flex}
.agitem{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;color:#fff;font-size:11px;font-weight:700;border:2px solid var(--bg);margin-left:-9px;transition:transform .25s}
.agitem:first-child{margin-left:0}
.agitem[data-lift]{transform:translateY(-6px)}
.agmore{width:30px;height:30px;border-radius:50%;background:var(--line);color:var(--fg);font-size:10px;font-weight:700;border:2px solid var(--bg);margin-left:-9px;cursor:default}
.agcallout{font-size:10px;color:var(--muted);height:12px}
js
const items = [...document.querySelectorAll('.agitem')];
const callout = document.getElementById('agcallout');
let auto = true, i = 0;
function paint() {
  items.forEach((it, idx) => it.toggleAttribute('data-lift', idx === i));
  callout.textContent = items[i].getAttribute('title');
}
items.forEach((it) => it.addEventListener('mouseenter', () => { auto = false; }));
paint();
setInterval(() => { if (!auto) return; i = (i + 1) % items.length; paint(); }, 900);

Used to summarize "who's involved" at a glance — a document's co-editors, a call's participants, a task's assignees. The "Avatar" entry elsewhere in this dictionary covers a single avatar and its photo-load fallback, while this one focuses on the composition pattern of arranging several avatars as one unit.

Overlapping circles leave no room for a visible name, so each avatar's accessible name needs to come from title or aria-label rather than visible text. A hover tooltip is enough on its own for mouse users, but touch devices have no hover, so the "+2" overflow button should also open a full list of names.

Picking a consistent rule for ordering — say, the most recently joined person goes first (or last) — makes positions feel stable rather than shuffling differently every time.