Skip to content
SuperCoach

Components · Data display

Avatar

Beta

A client's or coach's photo or initials.

Sara Al-Otaibi

12-week strength · Week 3

When to use

  • To help coaches recognise a client or teammate at a glance: in the client list, a check-in thread, a chat, the account menu.
  • To show who is in a group: the clients in a bootcamp, the coaches on a team.

When not to use

  • For the SuperCoach or Coach logo: use the logo tile from Brand. Brand avatars may use the chamfered corner; avatars of people are always round (Shape).
  • For progress photos or exercise images: those are content, not identity. Show them at full size, for example in a Carousel.
  • As the only way to identify someone. Put the name next to the avatar, or give the avatar a name.

Anatomy

OH
  1. 1. Container: round, clips the image, rounded-full
  2. 2. Image, or initials while it loads or when there is none
  3. 3. Badge (optional): a status dot or icon on the bottom end corner

Variants

Lina Farouk

Checked in today

Morning bootcamp

VariantUse for
ImageThe client's photo, when they uploaded one.
Initials (AvatarFallback)No photo, or while the photo loads. Muted fill and text, the same for everyone.
With badge (AvatarBadge)One status that matters in context, such as "Checked in today". Always also in text nearby.
Group (AvatarGroup + AvatarGroupCount)Up to 3 avatars that overlap, then "+3" for the rest.

States

StateWhat changesToken
LoadingInitials show until the image has loaded; set delayMs on the fallback to avoid a flash on fast connectionsbg-muted, text-muted-foreground
LoadedThe image fills the circlerounded-full
Error or no imageInitials stay. No broken-image iconbg-muted, text-muted-foreground
With badgeDot or icon with a ring that separates it from the photoring-background, bg-primary (default)

Avatars are not interactive. When an avatar opens a profile, the link around it (with the name) gets the focus ring.

Sizes

  • sm · 24px
  • default · 32px
  • lg · 40px

sm (24px) in dense tables and comment threads. default (32px) in lists and menus. lg (40px) in headers and cards. The badge and group count scale with the avatar. There are no sizing tokens yet; these are steps of the 4px spacing unit (QUESTIONS Q5).

Usage guidelines

  • Show the same person with the same avatar everywhere: the photo if there is one, otherwise the same initials.
  • In a group, show at most 3 avatars and a count. More becomes noise.
  • Use the badge for one status. Two badges on one avatar can't be told apart at 8px.

Sara Al-Otaibi

Checked in today

Do.The name and status are written next to the avatar.
SO
Don't.Initials alone. Screen readers spell out the letters, and coaches with many clients can't tell who it is.

Content guidelines

  • Initials: the first letter of the first name and of the family name, skipping the article "Al-" or "ال": Sara Al-Otaibi is "SO", Khalid Al-Qahtani is "KQ". Two letters at most, in capitals.
  • Arabic initials: the same rule: سارة العتيبي is "س ع". Arabic letters join, so put a zero-width non-joiner (U+200C) between the two letters. Without it, "سع" reads as a word.
  • Use the script the name was entered in. Don't transliterate a name to make initials.
  • Alt text: when the name is next to the avatar, the image is decorative: alt="" and aria-hidden on the avatar. When the avatar stands alone, give it the person's name: role="img" and aria-label="Sara Al-Otaibi". Never "avatar", "profile picture" or the file name.
  • Group count: "+3", and the group's accessible name says "and 3 more clients".

Accessibility

Avatars are not focusable and have no keyboard interaction.

  • An avatar next to a name is hidden from screen readers (aria-hidden), so the name isn't read twice.
  • A standalone avatar has role="img" and an aria-label with the name, so it is announced as "Sara Al-Otaibi, image", whether the photo or the initials show.
  • A group has one name for the whole stack: "Sara Al-Otaibi, Omar Haddad, Khalid Al-Qahtani and 3 more clients, image". The "+3" alone means nothing when read out.
  • A badge's meaning is written nearby or included in the avatar's name ("Omar Haddad, checked in today"). Color alone fails WCAG 1.4.1.
  • Initials use text-muted-foreground on bg-muted (5.28:1).

RTL

  • The badge sits on the bottom end corner (end-0), so it moves to the bottom left.
  • Groups overlap toward the end: -space-x-2 uses logical margins, so the first avatar is on the right and the count on the left.
  • Photos don't mirror. Initials follow the script of the name.

Tokens used

Read from components/ui/avatar.tsx at build time, so this list changes when the component does. Opacity modifiers such as /90 are shadcn hover and focus tints on top of the token.

Semantic color tokens used by this component
TokenUtilitiesSuperCoachCoach
--backgroundring-backgroundwhitewhite
--mutedbg-mutedneutral-100neutral-100
--muted-foregroundtext-muted-foregroundneutral-600neutral-600
--primarybg-primarybrand-600orange-500
--primary-foregroundtext-primary-foregroundwhitewhite
  • Layerz-(--z-raised)
  • Radiusrounded-full
  • Typetext-sm
  • Typetext-xs

Props

<Avatar>

Also takes every prop of Radix Avatar.Root

Avatar props
PropTypeDefault
size?"default" | "sm" | "lg""default"

<AvatarImage>

Also takes every prop of Radix Avatar.Image

No props of its own.

<AvatarFallback>

Also takes every prop of Radix Avatar.Fallback

No props of its own.

<AvatarBadge>

Also takes every prop of <span>

No props of its own.

<AvatarGroup>

Also takes every prop of <div>

No props of its own.

<AvatarGroupCount>

Also takes every prop of <div>

No props of its own.

Replaces in coach-admin

From the read-only audit of coach-admin: 40 style values, 40 uses.

coach-admin colors each client's initials with one of 16 muted background colors, assigned per client in src/lib/helpers/avatar.ts, with near-black text. The design system uses one muted fill for everyone, because those colors have no tokens and the text contrast was not checked. Whether to bring per-client colors back, as tokens, is an open question.

Classes and selectors

  • .avatar4
  • .avatar-status4
  • .avatar--xl3
  • .avatar--md3
  • .avatar--lg2
  • .avatar, .avatar-initials1
  • .avatar.avatar-xs1
  • .avatar--sm1

Files

  • src/lib/helpers/avatar.ts17
  • src/reusableComponents/Avatar/Avatar.scss13

The inventory lists the first 12 locations of each value, so file counts are a lower bound.

SCSS variables in these styles

  • $status-widthnot a color: spacing, size or layout
  • $layout-transition-speednot a color: spacing, size or layout

Data table, Badge, Shape, Content.