Skip to content
Monogem

Component · Core

Avatar

Overview

A profile picture that falls back to initials when the image is missing or fails to load. Avatar is not interactive by default.

Anatomy

A Container holds either an Image or a Fallback — only one renders at a time.

Live Example

Image

Ada LovelaceALAda LovelaceALAda LovelaceAL

Fallback (initials)

ALALAL

Code Example

avatar-showcase.tsx
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";

const SIZES = ["sm", "default", "lg"] as const;

/**
* A small inline SVG data URI so the "Image" row has a real, offline-safe
* source. In product code this is a photo URL; the fallback below covers the
* image being missing, still loading, or failing to load — all resolve to the
* same initials.
*/
const SAMPLE_IMAGE =
"data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='80'%20height='80'%3E%3Crect%20width='80'%20height='80'%20fill='%23d4d4d4'/%3E%3Ccircle%20cx='40'%20cy='32'%20r='14'%20fill='%23525252'/%3E%3Cpath%20d='M16%2076c0-13%2011-22%2024-22s24%209%2024%2022'%20fill='%23525252'/%3E%3C/svg%3E";

/**
* Live Avatar example — the three sizes, shown with a loaded image and with the
* initials fallback. Avatar is static: nothing here is clickable or focusable.
*/
export function AvatarShowcase() {
return (
<div className="flex flex-col gap-8">
<section className="flex flex-col gap-3">
<h3 className="text-sm font-medium leading-snug text-muted-foreground">
Image
</h3>
<div className="flex flex-wrap items-center gap-3">
{SIZES.map((size) => (
<Avatar key={size} size={size}>
<AvatarImage src={SAMPLE_IMAGE} alt="Ada Lovelace" />
<AvatarFallback>AL</AvatarFallback>
</Avatar>
))}
</div>
</section>

<section className="flex flex-col gap-3">
<h3 className="text-sm font-medium leading-snug text-muted-foreground">
Fallback (initials)
</h3>
<div className="flex flex-wrap items-center gap-3">
{SIZES.map((size) => (
<Avatar key={size} size={size}>
<AvatarFallback>AL</AvatarFallback>
</Avatar>
))}
</div>
</section>
</div>
);
}

Variants

VariantWhat renders
ImageThe photo, object-fit: cover, fills the container
Fallback (initials)1–2 initials, --muted-foreground text on --muted background

Two rendering modes, not color variants. The fallback shows when the image is missing, fails to load, or hasn’t loaded yet. An icon-only fallback isn’t part of Version 1.

Sizes

SizeTokenValueFallback text
sm--scale-832pxtext-xs font-medium leading-snug
default--scale-1040pxtext-sm font-medium leading-snug
lg--scale-1248pxtext-sm font-medium leading-snug

Sizes use the same Scale height steps as Button’s sm / default / lg, so an Avatar and a Button line up in a row. Fallback text stays at text-sm or smaller at every size.

States

Default

Avatar is static; it has no hover, focus, active, or disabled state.

If it needs to act on click, compose it with a Button.

Usage Guidance

Tokens

Avatar uses existing Monogem semantic and primitive tokens to stay consistent with the design system; it introduces no component-specific styling values.

TokenWhere used
--radius-fullCorner radius (circle)
--scale-8 / --scale-10 / --scale-12Container size: sm / default / lg
--mutedFallback background
--muted-foregroundFallback initials text

Do / Don’t

Do

  • Use a real photo when available; fall back to initials rather than a broken-image icon.
  • Keep fallback text to 1–2 characters.

Don’t

  • Stretch or distort the image — object-fit: cover keeps the crop centered and square.
  • Use Avatar as a clickable control on its own — wrap it in a Button or link.

Accessibility

  • Give the image meaningful alt text — the person’s name.
  • Use alt="" when visible text right next to the avatar already names the person.
  • Fallback initials are presentational; the avatar can be aria-hidden when adjacent text names the person.
  • No focus ring or tabindex — Avatar isn’t interactive, so it stays out of the tab order.
  • --muted-foreground on --muted is an existing Color pair that clears WCAG AA.