Avatar
StableA person or a store, as a small circle or square. It shows an image when there is one and initials on a quiet tint when there is not, so every customer, colleague and shop has a face in lists, menus and headers.
Sizes
Five sizes. md is the default. Initials are set at 40% of the size, so they stay in proportion at every step.
| Size | Pixels | Use it for |
|---|---|---|
xs | 20 | Inline with text, and in dense tables. |
sm | 24 | Rows in lists and tables. |
md | 32 | The default: menus, cards, activity. |
lg | 40 | Page headers and summaries. |
xl | 56 | A customer's or a colleague's own page. |
People and stores
People are circles, the default. Stores, brands and suppliers are rounded squares, with corners at 28% of the size. The shape also changes the initials: a person takes their first and last name, a store its first two words, which is how shop names are shortened.
Tints
Without an image, initials sit on one of six quiet tints: Orbit teal turned a little either way around the colour wheel, plus a slate. The tint is picked from the name, so the same person or shop gets the same colour everywhere, on every visit.
Choosing the tint yourself
Pass seed, such as a customer ID, when names can change or collide. Here two different customers share a name, and the seed tells them apart.
Status
A presence dot on the rim, for colleagues: online, away or busy. Each has its own shape as well as its own colour (a solid dot, a ring, a dot with a bar), so it reads without colour. The dot scales with the avatar.
Images and fallbacks
Pass src and the image fades in once it has loaded (a cached image shows at once). If it is missing or fails, the initials stay. Logos that must not touch the edge take fit="contain": the mark is inset on the canvas colour. With no name at all, a quiet silhouette stands in for a person and a shopfront for a store.
Groups
AvatarGroup overlaps avatars, each cut out of the one beneath by a ring in the surface colour. It sets the size and shape for all of them. With max, the rest collapse into a +N chip. Point at one and it comes forward.
On other surfaces
The rings and status dots are cut in the colour of the surface behind them: the canvas by default, and sunken cards set their own. On any other surface, set --o-avatar-surface on a parent to that surface's colour, or the cut-outs show as halos.
In both themes
All six tints for people and for stores, with status and a group, light and dark side by side.
Initials
initialsOf(name, kind) is the function the avatar uses, exported for anywhere else you need the same letters. It drops company suffixes (Ltd, Limited, LLP, PLC, Inc), a leading "The" and stray punctuation, and keeps accented letters.
| Name | As a person | As a store |
|---|---|---|
| Priya Shah | 'PS' | 'PS' |
| Callum James Reid | 'CR' | 'CJ' |
| Harbour Desk Co | 'HC' | 'HD' |
| The Copper Kettle Ltd | 'CK' | 'CK' |
| Thistle & Oak | 'TO' | 'TO' |
| Élodie Durand | 'ÉD' | 'ÉD' |
| Fernhill | 'F' | 'F' |
Guidelines
- Always pass name, even with an image: it names the avatar, and it is the fallback when the image fails.
- Use status for colleagues only. A customer does not have a presence.
- Keep a group to what fits: max={3} or max={4}, and let the +N chip say the rest.
- Put the name beside the avatar in lists. An avatar alone is a face, not an answer.
Accessibility
- The avatar is an image named by
name(oralt), with its status: "Priya Shah (Online)". The picture inside has an empty alt, so the name is read once. - When the name is written beside it, pass
alt="". The initials still come fromname, and the avatar is hidden from screen readers so the name is not read twice. statusLabelreplaces the words read for the status, for translations.- A group has the
grouprole: name it witharia-label("Staff on this order"). The +N chip reads as "2 more";overflowLabeltranslates it. - The lift on hover in a group is dropped under reduced motion.
Props
Avatar
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | None | Person or store name: the accessible name, the initials and the tint come from it. |
src | string | null | None | Image URL. Falls back to initials if it is missing or fails to load. |
alt | string | None | Accessible name when it should differ from name. An empty string hides the avatar from screen readers. |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | 20, 24, 32, 40 or 56px. Inherited from an AvatarGroup. |
shape | 'circle' | 'square' | 'circle' | Circle for people, square for stores and brands. Inherited from an AvatarGroup. |
fit | 'cover' | 'contain' | 'cover' | contain insets the image on the canvas colour, for logos. |
status | 'online' | 'away' | 'busy' | None | Presence dot on the rim, included in the accessible name. |
statusLabel | string | None | Words read for the status. Defaults to "Online", "Away" or "Busy". |
seed | string | None | Picks the tint instead of name, e.g. a stable customer ID. |
Avatar also accepts every native span attribute except children.
AvatarGroup
| Prop | Type | Default | Description |
|---|---|---|---|
max | number | None | Most avatars to show. The rest collapse into a +N chip. |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Size for every avatar in the group. |
shape | 'circle' | 'square' | None | Shape for every avatar in the group, unless one sets its own. |
overflowLabel | (hidden: number) => string | (n) => `${n} more` | Accessible text for the +N chip. |
AvatarGroup also accepts every native div attribute.
initialsOf(name, kind)
| Prop | Type | Default | Description |
|---|---|---|---|
nameRequired | string | None | The name to shorten. Returns an empty string when there is nothing to use. |
kind | 'person' | 'store' | 'person' | First and last word for a person; first two words for a store. |