A person's photo in a circle, or their initials when there is no photo.
Light
28 · compact
AT32 · row
AT36 · feed
AT56
AT88 · profile, 28/800
AT36 · with ring
MWDark
28 · compact
AT32 · row
AT36 · feed
AT56
AT88 · profile, 28/800
AT36 · with ring
MWSource:
Avatar.tsx. Photos, crops and the mascot: imagery.
When to use it
- Beside a person's name: in a Row, a feed post, a comment, a header, a profile.
- Inside a select trigger once a student is chosen.
Not on its own as the only way to tell people apart — the name is always beside it. Not as a button by itself; the row or header around it is the target.
Anatomy
| Part | Token |
|---|---|
| Sizes | 28 (avatarSize.compact), 32 (avatarSize.row, list rows and headers), 36 (feed), 56, 76, 88 (avatarSize.profile) |
| Shape | a circle |
| Photo | cover-fit, surface.tag behind it while it loads |
| Fallback | surface.tag disc with a 1px border.control edge |
| Initials | up to two letters, weight 500, text.secondary, about 0.42 of the size; at 88 it is 28/800, from typography.metric |
| Ring | with beltRank: spacing.s2 gap, then 1px border.control |
States
- Photo, initials (no photo, or it failed), and with ring as drawn.
- No pressed, focus or disabled state of its own: those belong to the row or header it sits in.
- A missing name shows "?" rather than nothing.
Content
- Initials are the first letter of the first name and of the last: Ana Torres is "AT".
- A rank never changes the ring's colour. The ring says "this person has a rank"; the rank itself is a belt dot and words.
Accessibility
- The image's accessible name is the person's name, or "Profile photo" when there is none. Inside a row, the row's label already says the name, so the avatar adds nothing to it.
- The fallback disc is nearly the colour of the page and of a card, so its
border.controledge is the only thing that shows where the avatar is.border.controlonsurface.cardis 3.53:1 in light and 3.16:1 in dark.
Do and don't
AT
Do
The ring is 1px border.control, every rank, both themes.
AT
Don’t
A ring in the belt’s colour reads as a second swatch, not a frame.
Code
import { Avatar } from '../../components/ui';
<Avatar uri={user.avatar_url} name={user.full_name} size={32} />
<Avatar uri={user.avatar_url} name={user.full_name} size={88} beltRank={user.belt_rank} />