Avatar
Shows who did something: a person, an agent or a source.
Examples
AMMC
AM
MC
and 2 more: Jon Reyes, Sam Okoye
Type
- AMMC
persondefault
agent
source
Sizes
- M
2xs
- M
xs
- M
sm
- MC
defaultdefault
- MC
lg
States
- AM
image
- MC
initials
no name
- MC
status
agent running
- AMand 2 more: Jon Reyes, Sam Okoye
+N focus
Usage
When to use it
- Use
- A row, message or event shows who did it: a person or an agent.
- Use
- Several people or agents share one thing and the count matters more than each name.
- Use
- A linked source or integration needs its icon: type="source".
- Not for
- The thing has a kind but no identity (a run, a key). Use Badge.
- Not for
- The person needs every name readable at once. Use Item.
- Not for
- Presence or progress is the whole point. Use Status.
Rules
9 rules
- Must
- Pass name and let Avatar make the initials and the accessible name. Because without name the root gets no role="img" or aria-label, and hand-cut initials skip the fit that drops to one letter.
- Must
- Pass the full display name, not a handle fragment. Because name is the accessible name and the +N hint, so a screen reader hears "am" and initials come out as AM.
- Must
- Wrap more than 4 avatars in AvatarGroup with max 3 to 5 and name each one. Because a bare row never folds, and the +N can only list the hidden people that carry a name.
- Must
- Pass decorative when the name is written next to the avatar. Because otherwise a screen reader reads the name twice, once from the avatar and once from the text.
- Must
- Use AvatarBadge with a label that names the status, such as Online. Because a colored dot says nothing to a screen reader, while the badge label joins the name as "Maya Chen, Online".
- Must
- Serve a source src from your own origin or cache, never a favicon service URL. Because a favicon service learns every domain the person cites and breaks when it is down or blocked.
- Never
- Show an agent as a round avatar with a robot photo; use type="agent". Because round means a person in Quartz, so a round agent reads as a teammate wrote the change.
- Never
- Give initials a gradient or a hue per person. Because hue names a kind in Quartz, so a pink person reads as a kind of actor that does not exist.
- Should
- Say the count in words beside a group that folds more than 12 names. Because the +N hint lists every hidden name in one line, which stops being readable past a dozen.
Accessibility
5 checks
- Avatar is role="img" named by name or aria-label; decorative sets aria-hidden.
- A group is a list named by label; +N is a list item that names the hidden people.
- Tab focuses a +N that has names and opens the list; Escape closes it; a tap toggles it.
- AvatarBadge label joins the avatar name: "Maya Chen, Online, image".
- An avatar with no name and no aria-label has no accessible name; always pass one.
Edge cases
12 edge cases
- Very long name
- Two initials and a long accessible name; the box never grows.
- One-word or one-letter name
- One letter gives one initial; a word gives its first two; 24px and under show one.
- No name, no image
- An empty edge, round for a person; sources show a globe. Pass aria-label.
- 40 avatars, max 4
- Shows 3 and +37; the hint lists 37 names and wraps at 420px.
- Right to left
- The group overlaps with logical margins, from the right.
- Zoom 200%
- Initials measure themselves: two letters drop to one, then scale to the box.
- Slow image
- The fallback holds the same box; the image swaps in with no shift.
- Broken src
- The broken image never paints; the fallback stays.
- Inside a link
- Make the avatar decorative and let the link carry the name.
- src changes ten times in a second
- The fallback stays until the last one loads.
- 200 avatars with initials
- Each adds a ResizeObserver; pass src or hide initials in rows that do not need a person.
- Forced colors
- Fallback and +N keep a 1px outline; the source globe shows in currentColor.
API
7 props
Avatar type'person' | 'agent' | 'source'default'person'Avatar size'2xs' | 'xs' | 'sm' | 'default' | 'lg'default'default'Avatar namestringAvatar srcstringAvatar decorativebooleandefaultfalseAvatarBadge status, labelStatusValue, stringAvatarGroup max, label, sizenumber, string, size
Tokens
12 tokens
--radius-soft- 6px
--radius-full- 999px
--line-control- oklch(var(--ink-c) / 0.16)
--text-1- var(--ink)
--type-label-sm- 400 12px/16px var(--font-sans)
--type-label- 400 14px/16px var(--font-sans)
--accent-tint- var(--surface-selected)
--accent-label- var(--text-1)
--surface-page- var(--paper)
--line-frame- oklch(var(--ink-c) / var(--line-frame-alpha))
--mark-size- 8px
--ring-cutout- 2px