/*
* Avatar-group — element (display)
*
* Overlapping stack of avatars. Used to show participants, owners, or
* any collection of people associated with a thing. CSS-only.
*
* <div class="avatar-group">
* <span class="avatar">A</span>
* <span class="avatar">B</span>
* <span class="avatar">C</span>
* <span class="avatar -overflow">+5</span>
* </div>
*/
@layer malevich.components {
.avatar-group {
--avatar-group-overlap: calc(var(--size-control-m) * 0.4);
display: inline-flex;
align-items: center;
isolation: isolate;
}
.avatar-group > .avatar {
border: var(--border-width-emphasis) solid var(--color-surface-canvas);
position: relative;
margin-inline-start: calc(-1 * var(--avatar-group-overlap));
}
.avatar-group > .avatar:first-child {
margin-inline-start: 0;
}
/* Later siblings stack visually below the earlier ones — hover the
* earlier ones to read them clearly. Z-index decreases along the
* row so the first avatar sits on top.
*/
.avatar-group > .avatar:nth-child(1) { z-index: 6; }
.avatar-group > .avatar:nth-child(2) { z-index: 5; }
.avatar-group > .avatar:nth-child(3) { z-index: 4; }
.avatar-group > .avatar:nth-child(4) { z-index: 3; }
.avatar-group > .avatar:nth-child(5) { z-index: 2; }
.avatar-group > .avatar:nth-child(6) { z-index: 1; }
/* Overflow indicator: e.g. "+5" appended after visible avatars */
.avatar-group > .avatar.-overflow {
background-color: var(--color-surface-raised);
color: var(--color-ink-regular);
}
/* Variants */
.avatar-group.-tight {
--avatar-group-overlap: calc(var(--size-control-m) * 0.6);
}
.avatar-group.-loose {
--avatar-group-overlap: calc(var(--size-control-m) * 0.15);
}
/* When sitting on a non-canvas surface, expose the border tone via
* a custom property the author can override. Defaults to canvas.
*/
.avatar-group.-on-raised > .avatar {
border-color: var(--color-surface-raised);
}
}
This component is pure CSS — no JavaScript required.
# Avatar-Group — AGENTS.md
> Auto-generated from `avatar-group.docs.md` + the modifier applicability matrix.
> Edit those source files; this file regenerates on build.
## Identity
- **Component:** `avatar-group`
- **Layer:** elements
- **Status:** stable
- **Last updated:** 2026-05-19
## Summary
- Showing 2-6 people associated with a thing.
## Variants
| Variant | Class | Use for |
|-----------|------------------------------|----------------------------------------|
| Default | `.avatar-group` | Standard overlap |
| Tight | `.avatar-group.-tight` | More overlap (denser) |
| Loose | `.avatar-group.-loose` | Less overlap (more visible) |
| On raised | `.avatar-group.-on-raised` | Border tone matches raised surface |
## Modifier applicability
Per ADR-0007. Modifiers attach via `data-{category}="value"` attributes.
| Category | Accepts |
|---|---|
| `background` | — |
| `surface` | — |
| `effect` | — |
| `shader` | — |
| `rhythm` | `compact`, `regular` |
| `motion` | — |
| `behavior` | — |
## Anatomy
```html
<div class="avatar-group">
<span class="avatar">A</span>
<span class="avatar">B</span>
<span class="avatar">C</span>
<span class="avatar -overflow">+5</span>
</div>
<!-- With images -->
<div class="avatar-group -tight">
<img class="avatar" src="alex.jpg" alt="Alex" />
<img class="avatar" src="bo.jpg" alt="Bo" />
<img class="avatar" src="chris.jpg" alt="Chris" />
</div>
```
The component uses CSS to:
- Negative margin each avatar onto the previous one
- Add a border in the surface color so each avatar reads as separate
- Stack first avatar on top via z-index
## Tokens consumed
- `--size-control-m` — base avatar size for overlap math
- `--color-surface-canvas` — border (default)
- `--color-surface-raised` — border (on-raised variant) + overflow bg
- `--color-ink-regular` — overflow text
- `--border-width-emphasis` — border thickness
## Accessibility contract
The group itself is decorative — there is no list semantics. If the
group represents a meaningful collection (e.g. assignees to a task),
wrap it in a labeled container:
```html
<div aria-label="Assigned to 8 people">
<div class="avatar-group">
<span class="avatar" aria-label="Alex">A</span>
<span class="avatar" aria-label="Bo">B</span>
<span class="avatar -overflow" aria-label="and 6 more">+6</span>
</div>
</div>
```
The individual avatar accessibility is the consumer's choice — for an
image avatar, `<img alt="">` is correct; for an initials avatar, an
`aria-label` carries the name.
## Guidance
### Do
- Limit visible avatars to 4-6 + an overflow indicator.
- Order most-important first (they sit on top).
- Match the border color to the surface the group sits on.
### Don't
- Don't put a list of 20 avatars in a group. Use a different display.
- Don't mix avatar sizes within one group — overlap math assumes
uniform size.