Avatar Group
A row of overlapping avatars with a trailing +N overflow chip, for a contributor, attendee, or reviewer stack.
Live demo
Avatar Group overlaps a set of Avatar children into a compact stack, the shape a contributor list, an attendee row, or a "who's viewing" strip takes. Each avatar carries a ring in the page background so the overlap reads as distinct faces rather than a blur, and later avatars sit over earlier ones.
Slot the avatars you want shown and set overflow to the number of people beyond them, and the group renders a trailing +N chip in the neutral tone (its accessible name reads "N more"). size matches the chip to the avatars you used, and spacing tightens or loosens the overlap. It's a role="group"; give it a label to name the set. The overflow count is explicit rather than auto-counted so the stack renders identically with no JavaScript, on the server, and in the browser.
When to use
How this component composes with the rest of the set.
Props
4 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
+N chip (named "N more" for assistive tech); zero or omitted renders no chip. Explicit rather than auto-counted, so the stack is identical with no JavaScript. | ||||
+N chip to match the avatars you slotted (each Avatar still sets its own size). | ||||
snug stacks them tighter, loose spreads them out. | ||||
Appearance
Sizes
sm
Compact, for dense lists.
md
Default.
lg
Large, for headers.
xl
Extra large.
States
avatar-hover
Hovering or focusing an avatar raises it above its neighbours so a covered face reads in full.
Anatomy
The named parts that make up the component. A ::part() handle is reachable from your own stylesheet; the class beside it is the component's internal selector, which a shadow boundary keeps to itself.
group
The role="group" row that overlaps its slotted avatars.
overflow
The trailing +N chip summarizing the avatars beyond the shown set.
Tokens & coverage
What the component consumes, checked live against what the algorithm produces.
Live coverage check against the xtyle-default register
(derive(xtyleDefault, { anchors }) →
coverComponent(manifest, register)). Every token this component
consumes must be a key the algorithm produces.
--bg-0--border-thick--font-sans--leading-tight--neutral-bg--neutral-text--radius-full--space-2--space-3--space-4--space-6--space-7--space-8--text-body--text-lg--text-sm--text-xs--weight-semiboldSlots
The Avatar children to overlap, in stacking order (the first sits at the bottom of the stack).
Accessibility
Code
A contributor stack
Overlapping avatars with a +N chip for the rest; each keeps its own tone.
<xtyle-avatar-group label="Contributors" overflow="3">
<xtyle-avatar alt="Ada Lovelace" tone="accent">AL</xtyle-avatar>
<xtyle-avatar alt="Alan Turing" tone="success">AT</xtyle-avatar>
<xtyle-avatar alt="Grace Hopper" tone="warn">GH</xtyle-avatar>
<xtyle-avatar alt="Katherine Johnson" tone="info">KJ</xtyle-avatar>
</xtyle-avatar-group><script lang="ts">
import { AvatarGroup, Avatar } from "@xtyle/svelte";
const people = [
{ name: "Ada Lovelace", initials: "AL", tone: "accent" },
{ name: "Alan Turing", initials: "AT", tone: "success" },
{ name: "Grace Hopper", initials: "GH", tone: "warn" },
{ name: "Katherine Johnson", initials: "KJ", tone: "info" },
];
const shown = people.slice(0, 4);
</script>
<AvatarGroup label="Contributors" overflow={people.length - shown.length + 3}>
{#each shown as p}
<Avatar alt={p.name} tone={p.tone}>{p.initials}</Avatar>
{/each}
</AvatarGroup>---
import { AvatarGroup, Avatar } from "@xtyle/astro";
const people = [
{ name: "Ada Lovelace", initials: "AL", tone: "accent" },
{ name: "Alan Turing", initials: "AT", tone: "success" },
{ name: "Grace Hopper", initials: "GH", tone: "warn" },
{ name: "Katherine Johnson", initials: "KJ", tone: "info" },
];
---
<AvatarGroup label="Contributors" overflow={3}>
{people.map((p) => <Avatar alt={p.name} tone={p.tone}>{p.initials}</Avatar>)}
</AvatarGroup>Sizes and spacing
size matches the chip to the avatars and spacing="snug" tightens the overlap for a dense viewer strip.
<xtyle-avatar-group size="sm" spacing="snug" overflow="12" label="Viewers">
<xtyle-avatar alt="Ada" tone="accent" size="sm">AD</xtyle-avatar>
<xtyle-avatar alt="Alan" tone="success" size="sm">AL</xtyle-avatar>
<xtyle-avatar alt="Grace" tone="warn" size="sm">GR</xtyle-avatar>
</xtyle-avatar-group><script lang="ts">
import { AvatarGroup, Avatar } from "@xtyle/svelte";
</script>
<AvatarGroup size="sm" spacing="snug" overflow={12} label="Viewers">
<Avatar alt="Ada" tone="accent" size="sm">AD</Avatar>
<Avatar alt="Alan" tone="success" size="sm">AL</Avatar>
<Avatar alt="Grace" tone="warn" size="sm">GR</Avatar>
</AvatarGroup>---
import { AvatarGroup, Avatar } from "@xtyle/astro";
---
<AvatarGroup size="sm" spacing="snug" overflow={12} label="Viewers">
<Avatar alt="Ada" tone="accent" size="sm">AD</Avatar>
<Avatar alt="Alan" tone="success" size="sm">AL</Avatar>
<Avatar alt="Grace" tone="warn" size="sm">GR</Avatar>
</AvatarGroup>