Avatar
Displays a user's profile image, initials, or a fallback icon to represent a person or organisation. Use to identify users in lists, comments, assignments, and profile surfaces. Don't use as a decorative element — always pair with a name or accessible label.
FigmaDescription
Renders a circular or square container showing a user's photo, their initials derived from their name, or a generic person icon as a fallback. Sizes range from extra-small (used in dense data tables) to large (used in profile headers).
Comment threads on consultations, stakeholder and contact list rows, task assignment fields, activity feeds, user profile headers, and team member panels.
Government engagement platforms involve many named participants — councillors, community members, internal officers. A consistent avatar treatment reduces visual noise while keeping content clearly attributed, and ensures people can quickly identify who said or did something without reading every name.
Anatomy
| Part | Required? | Notes |
|---|---|---|
| Container | Required | Circular (default) or square shape. Clips the image or centres the initials/icon. Size variants control the container's width and height. |
| Image | Optional | User-supplied photo. Rendered as a background image or <img> element. If the image fails to load, the component falls back to initials, then to the generic icon. |
| Initials label | Optional | One or two characters derived from the user's display name (e.g. 'BM' for Bonnie Mercer). Shown when no image is available. Uses --op-font-body at a size proportional to the container. |
| Fallback icon | Recommended | A generic person silhouette icon rendered when neither image nor initials are available. Uses wa-icon internally. |
| Status indicator | Optional | A small dot overlaid on the bottom-right corner of the container. Uses --op-color-status-* tokens to communicate online, away, busy, or offline presence. Not used in Open Point or Social Point at this time. |
| Accessible label | Required | An aria-label or visually-hidden text string that names the person or entity. Must always be present — the visual representation alone is not sufficient. |
Variants
Image
Displays the user's actual profile photo
When the user has uploaded a photo and the image URL is available and trusted
Initials
Displays one or two characters from the user's name on a coloured background
When no photo is available but the user's name is known; preferred over the icon fallback for named users
Icon (fallback)
Displays a generic person silhouette
When neither a photo nor a name is available, or when representing an anonymous or unknown participant
Square
Represents an organisation or non-person entity
Organisation logos, agency crests, or system accounts where a circular shape would imply a person
Sizes
States
| State | Behaviour |
|---|---|
| Default | Displays image, initials, or icon at rest. No interactive affordance unless wrapped in a link or button. |
| Image loading | Shows a neutral background using --op-color-bg-subtle while the image fetches. Transitions to image, initials, or icon on load or error. |
| Image error | Falls back automatically to initials if a name is available, or the generic icon if not. No broken-image indicator is shown. |
| Focused (when interactive) | When the avatar is wrapped in an anchor or button, focus ring appears: 3px solid --op-color-interactive-focus, offset 2px. The ring follows the container shape (circle or square). |
| Hovered (when interactive) | Slight overlay using --op-color-bg-overlay at reduced opacity signals the element is clickable. Cursor changes to pointer. |
| Selected / active | A border or ring using --op-color-interactive-default distinguishes a selected avatar in a multi-select or assignment UI. |
Usage guidelines
When to use
- Attribute a comment, note, or action to a named person in a consultation or engagement activity.
- Show which officer is assigned to a stakeholder record or task in Open Point.
- Display participants in a team or working group panel.
- Represent the signed-in user in a navigation bar or account menu.
When not to use
- Do not use as a decorative illustration — every avatar must correspond to a real person, organisation, or authenticated account.
- Do not use for status icons, category icons, or abstract concepts — use wa-icon or Badge instead.
- Do not use the XSmall (16px) variant without an immediately adjacent visible name; it cannot be read in isolation.
- Do not stack more than five avatars in an overflow group without a count indicator showing the total — use an avatar group pattern with a '+N' overflow badge.
Do / Don't
Do
Always provide an aria-label or visually-hidden name so screen reader users hear who the avatar represents.
Don't
Don't rely on image alt text alone — alt text is suppressed when the image fails to load and initials are shown instead.
Do
Use the initials variant when a name is known but no photo is available — it is more personal and easier to distinguish than the generic icon.
Don't
Don't show a generic icon when the user's name is available; it erodes trust and makes attribution harder.
Do
Pair every avatar with a visible name label in data tables, lists, and comment threads.
Don't
Don't use an avatar alone as the only identifier in a table row — government users often need to copy or read a full name.
Do
Use the square variant consistently for organisations and the circular variant for people.
Don't
Don't mix circle and square shapes for the same entity type within the same view.
Layout & Spacing
Container sizes: xsmall: 16 x 16px — minimal footprint for very dense contexts; inline within a sentence or a compact data cell — use sparingly and always with an adjacent visible name small: 24 x 24px — compact representation for lists and tables; stakeholder list rows, comment author attribution, activity feed items medium: 32 x 32px — default size for most product surfaces; assignment fields, team panels, sidebar participant lists large: 48 x 48px — prominent identification; profile headers, drawer panels displaying a stakeholder's full record xlarge: 64 x 64px — hero-level identification; dedicated profile pages or account settings — rarely used in data-dense views
Internal padding (initials/icon): 0 — content is centred with flexbox. Gap between avatar and adjacent name label: --op-space-8 (8px) for medium/large; --op-space-4 (4px) for small/xsmall. Status indicator dot size: 8px (medium), 10px (large), 12px (xlarge). Status indicator offset: positioned absolute, bottom -1px, right -1px, bordered 2px solid --op-color-bg-primary to create separation.
Tokens
| Part | Token | Value |
|---|---|---|
| Container background (initials variant) | --op-color-bg-subtle | Default neutral background; products may apply a hashed colour per user for differentiation |
| Initials text | --op-color-text-primary | Ensures contrast against --op-color-bg-subtle |
| Fallback icon | --op-color-text-secondary | Slightly muted to distinguish from initials text |
| Focus ring | --op-color-interactive-focus | 3px solid, offset 2px — applies only when avatar is interactive |
| Hover overlay | --op-color-bg-overlay | Applied at 10% opacity over the container when interactive |
| Selected border | --op-color-interactive-default | 2px solid ring when avatar is in a selected/active state |
| Status — success (online) | --op-color-status-success | Green dot |
| Status — warning (away) | --op-color-status-warning | Amber dot |
| Status — error (busy) | --op-color-status-error | Red dot |
| Status — neutral (offline) | --op-color-text-tertiary | Grey dot |
| Container border radius (circular) | --op-radius-pill | 999px — produces a circle at all sizes |
| Container border radius (square/org) | --op-radius-md | 8px — softened corners for organisation avatars |
| Container size | --size (set via data-size) | wa-avatar's own --size custom property; Orbit's data-size attribute in component-overrides.css maps xsmall/small/medium/large/xlarge to hardcoded 16/24/32/48/64px values — not aliased to a token, since no spacing/size scale is exposed to that file |
Engineering notes
- The wa-avatar web component accepts an image attribute for the photo URL, a label attribute for the accessible name, and an initials attribute for the fallback text. Always set label — it maps to aria-label on the host element.
- wa-avatar has no built-in size attribute — it is sized entirely via the --size CSS custom property. Orbit defines a data-size extension (xsmall/small/medium/large/xlarge) in component-overrides.css that maps to --size using hardcoded 16/24/32/48/64px values (not token references — component-overrides.css only has access to wa-theme.generated.css, which carries no spacing/size scale). Omitting data-size renders medium (32px).
- Image load errors are handled internally by wa-avatar; no external error handling is required. The component falls back to initials, then to the built-in person icon.
- To make an avatar interactive (e.g. linking to a stakeholder profile), wrap it in a native
<a>element rather than adding click handlers directly to wa-avatar. This preserves keyboard and screen reader behaviour. - When rendering initials, pass the full display name in the label attribute and derive initials separately. Do not pass raw database IDs or email addresses as the label.
- For avatar groups (stacked overflow), render each wa-avatar with a negative left margin of --op-space-8 and a border using --op-color-bg-primary to visually separate stacked items. The overflow count badge should use the Badge component with a neutral variant.
- The square variant is achieved by setting shape="square" on wa-avatar, which applies --op-radius-md instead of --op-radius-pill.
- Colour-coding initials backgrounds per user should use a deterministic hash of the user ID mapped to a set of approved --op-color-*-subtle background tokens — never use arbitrary hex values.
Keyboard interaction
| Key | Action |
|---|---|
| Tab | Moves focus to the avatar when it is wrapped in an interactive element (link or button). Non-interactive avatars are not focusable. |
| Enter | Activates the link or button wrapping the avatar (e.g. opens the stakeholder profile drawer). |
| Space | Activates a button-wrapped avatar. Has no effect on link-wrapped avatars. |
Why it matters
Government platforms are used by a wide range of staff including those using assistive technology. An avatar without an accessible name leaves screen reader users without context about who performed an action or who is assigned to a record — this is especially important in audit trails and comment threads where attribution is a compliance requirement.
Focus
Focus is only applied when the avatar is wrapped in an interactive element. The focus ring (3px solid --op-color-interactive-focus, offset 2px) follows the container shape — circular for people, square-with-radius for organisations. Focus must never be suppressed with outline: none without a replacement ring.
ARIA
| Role or attribute | When to use | Example |
|---|---|---|
aria-label | Set on the wa-avatar host element via the label attribute to name the person or organisation. | <wa-avatar label="Bonnie Mercer" initials="BM"></wa-avatar> |
aria-hidden="true" | Set on the avatar when it is immediately adjacent to a visible name element, to avoid double-announcing the name to screen readers. | <wa-avatar aria-hidden="true" initials="BM"></wa-avatar><span>Bonnie Mercer</span> |
role="img" | Applied internally by wa-avatar when an image is displayed. Do not override. | Managed by the web component — no action required. |
alt | If using a plain <img> element instead of wa-avatar, set alt to the person's name. Set alt="" only when an adjacent visible name makes it redundant. | <img src="/avatars/bm.jpg" alt="Bonnie Mercer" /> |
Contrast
Initials text (--op-color-text-primary) on the default background (--op-color-bg-subtle) must meet 4.5:1 contrast ratio for normal text (WCAG 1.4.3 AA). If custom background colours are used for colour-coded initials, each colour must be independently verified to maintain 4.5:1 against the initials text colour. The fallback icon (--op-color-text-secondary on --op-color-bg-subtle) must meet 3:1 for non-text contrast (WCAG 1.4.11). Status indicator dots must meet 3:1 contrast against both the container and the adjacent page background (--op-color-bg-primary).
Touch targets
The minimum interactive touch target is 44x44px (WCAG 2.5.5). When using the small (24px) or medium (32px) avatar as an interactive element, extend the tap target using padding or a pseudo-element — do not increase the visible avatar size. The large (48px) and xlarge (64px) variants meet the minimum natively.
Things to avoid
- Do not remove the focus ring from interactive avatars — government accessibility requirements mandate visible focus indicators.
- Do not rely on colour alone to convey status (e.g. online/offline) — pair the status dot with a tooltip or visually-hidden label.
- Do not use CSS background-image to render the avatar photo without a separate accessible text alternative.
- Do not truncate the aria-label — use the full display name, not initials or a username.