Components

Avatars & media

Represent users, accounts, and entities. Avatars surface identity at a glance — initials when no image is available, stacked when space is tight, paired with text in the media object pattern.

Stable ws-avatar ws-avatar-group ws-media

Sizes

Four sizes cover every density level — from inline mentions to full profile views. Always match avatar size to the surrounding text size and row height.

JD xs · 24px
JD sm · 32px
JD md · 40px
JD lg · 56px
<span class="ws-avatar ws-avatar--xs">JD</span>
<span class="ws-avatar ws-avatar--sm">JD</span>
<span class="ws-avatar ws-avatar--md">JD</span>
<span class="ws-avatar ws-avatar--lg">JD</span>
ModifierSizeFontTypical use
ws-avatar--xs24 × 24 px10 pxInline mentions, compact tags, table badges
ws-avatar--sm32 × 32 px12 pxData table rows, activity feeds, nav items
ws-avatar--md40 × 40 px14 pxDefault — cards, comment threads, dropdowns
ws-avatar--lg56 × 56 px18 pxProfile drawers, account headers, detail pages

Initials & color variants

Render the first letter of given name + first letter of surname when no photo is available. Assign color deterministically from the user's ID — the same person always gets the same color, building recognition over time.

AJ BK CL DM EN FP
<span class="ws-avatar ws-avatar--md">AJ</span>                <!-- navy (default) -->
<span class="ws-avatar ws-avatar--md ws-avatar--green">BK</span>
<span class="ws-avatar ws-avatar--md ws-avatar--amber">CL</span>
<span class="ws-avatar ws-avatar--md ws-avatar--teal">DM</span>
<span class="ws-avatar ws-avatar--md ws-avatar--coral">EN</span>
<span class="ws-avatar ws-avatar--md ws-avatar--violet">FP</span>
Deterministic color assignment

Derive the color from a stable property of the user — their numeric ID modulo the number of variants works well: const idx = userId % COLOR_VARIANTS.length. Never randomize on each render — the same person must always appear in the same color for recognition to form.

ModifierBackgroundForeground
default--ws-green-01 (#319B42)White
ws-avatar--green--green-600White
ws-avatar--amber--amber-600White
ws-avatar--teal#0d7f7fWhite
ws-avatar--coral#c0473cWhite
ws-avatar--violet#6d3db8White

With photo

Drop an <img> inside .ws-avatar. The image fills and clips to a circle automatically. Always provide a meaningful alt attribute on the image.

<span class="ws-avatar ws-avatar--md">
  <img src="/users/jane-doe.jpg" alt="Jane Doe" />
</span>
Always handle the broken-image state

If a profile photo fails to load, fall back to initials. Use an onerror handler that removes the <img> and sets the initials text on the parent span so the background color still shows.

Status indicator

Wrap the avatar in .ws-avatar-wrap and add a .ws-avatar-status sibling to overlay a presence dot. Use only on surfaces where real-time presence is genuinely meaningful — not decorative.

JD
Online
SR
Away
MK
Busy
PL
Offline
<div class="ws-avatar-wrap">
  <span class="ws-avatar ws-avatar--md">JD</span>
  <span class="ws-avatar-status ws-avatar-status--online" aria-label="Online"></span>
</div>
ModifierColorMeaning
ws-avatar-status--onlineGreenUser is currently active and reachable
ws-avatar-status--awayAmberIdle or temporarily unavailable
ws-avatar-status--busyRedIn a meeting or Do Not Disturb
ws-avatar-status--offlineGrayNot logged in or status unknown

Avatar groups

Stack multiple avatars with .ws-avatar-group. Beyond 3–4 avatars, collapse remaining members into a +N overflow counter to prevent visual noise.

3 assignees

AJ BK CL

7 assignees — overflow after 3

AJ BK CL +4

md size group

AJ DM FP +2
<div class="ws-avatar-group">
  <span class="ws-avatar ws-avatar--sm">AJ</span>
  <span class="ws-avatar ws-avatar--sm ws-avatar--green">BK</span>
  <span class="ws-avatar ws-avatar--sm ws-avatar--amber">CL</span>
  <!-- remaining 4 collapsed -->
  <span class="ws-avatar ws-avatar--sm ws-avatar--overflow">+4</span>
</div>
Reveal hidden names on hover

Wrap the overflow counter in a ws-tooltip-wrap to list all hidden member names on hover. Set aria-label="4 more: David M, Elena N, Frank P, Grace Q" on the overflow element so screen readers can announce them.

Media object

The media object is the most common avatar pattern — an avatar left-aligned with a name and secondary metadata beside it. Use in lists, feeds, comment threads, table rows, and notification panels.

AJ
Alexandra Johnson
Account Executive · San Francisco
BK
Brian Kim
Senior Underwriter · Chicago
Active
CL
Clara Lin
Client Success Manager · New York
Away
DM
David Mercer
Risk Advisor · Boston
<div class="ws-media">
  <span class="ws-avatar ws-avatar--md">AJ</span>
  <div class="ws-media__body">
    <div class="ws-media__name">Alexandra Johnson</div>
    <div class="ws-media__sub">Account Executive · San Francisco</div>
  </div>
  <!-- optional: badge, button, or time stamp -->
</div>

Accessibility

Avatars represent a specific person — they are not decorative. Every avatar must either carry a text alternative or appear next to a visible name that acts as its label.

ScenarioRequired markup
Avatar with a visible name nearby (media object, table row)Add aria-hidden="true" to the avatar element — the adjacent text already labels it.
Standalone avatar, no adjacent nameAdd aria-label="Jane Doe" directly on .ws-avatar.
Avatar with a photoProvide alt="Jane Doe" on the <img> — the circle container should be aria-hidden="true".
Status indicator dotaria-label="Online" on .ws-avatar-status. Do not leave it unlabeled.
Overflow counter (+N)aria-label="4 more assignees: David M, Elena N…" and a tooltip listing all names.
Color alone is not enough

The six color variants are a visual aid, not an identification mechanism. Don't rely on avatar color to convey meaning — always pair it with a name or label.

Usage

AJ
Alexandra Johnson
Policy owner
Always pair avatar with a visible name
AJ BK CL
Don't show avatars without any name context
AJ BK CL +4
Cap at 3, collapse the rest into +N
A B C D E F G
Don't stack 7+ avatars without truncation
JS Use sm in table rows
Match avatar size to row density
JS lg in a data table
Don't use lg avatars inside dense data tables