Design system/Components
Avatar
One way to draw anyone's face: their photo if there is one, otherwise the first letter of their name on a circle. Before this component, 29 different places hand-wrote avatars, and an uploaded photo only showed up on the profile page.
In codecomponents/avatar.tsxlib/ui.ts (avatarGradient)
Variants
The default tone is contrast: charcoal with a light letter. accent is orange, for the user themselves or something that must be seen. gradient is for lists of people: the color is derived from a hash of the name, so each person always gets the same color and two people side by side rarely match.
18S24S32S44S58contrastOaccentOgradient?name=""Rules
- The letter size is 42 percent of the circle size and never goes below 9px, so one component covers everything from an 18px stack to the 58px profile header.
- If the name is empty, "?" is shown; an empty circle looks like an error.
- When there's no src, the first letter is drawn; the component doesn't catch image load errors itself, so clear the URL of a photo that no longer exists.
- A photo has alt text with the person's name; a decorative avatar next to the full name doesn't repeat the name.
<Avatar name={user.name} src={user.avatar} size={32} />
<Avatar name={member.name} tone="gradient" size={24} />Sizes and color
size 32 · tone contrastmax(9, round(size × 0.42))Weight 600999px--dark-contrast on --dark12.94 : 1 · 14.62 : 1#fff on --accent3.63 : 1 · 3.37 : 1linear-gradient(140deg, hsl(h 58% 52%), hsl(h+42 52% 36%))h from the name hash40px · 16px≤ 720px16px · 9px- The photo is an <img> with alt equal to the name and object-fit: cover. The first letter is a <span> and screen readers read that letter; next to the full name, prevent the repetition with aria-hidden on the container or a suitable title.
- In gradient, the letter is white and the color's lightness depends on the name hash; that's why a gradient avatar always appears next to a name, never alone.
- Avatar accepts onClick but isn't a button itself; put a tappable avatar inside a <button>.
Do
One Avatar with name and src.
Don't
A hand-made <span className="avatar">{name[0]}</span>; the photo never shows up in it.
Do
tone="gradient" for lists of people.
Don't
A random color on every render; each person should always have one color.
Related pages