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
Fallback (initials)
Code Example
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
| Variant | What renders |
|---|---|
| Image | The 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
| Size | Token | Value | Fallback text |
|---|---|---|---|
| sm | --scale-8 | 32px | text-xs font-medium leading-snug |
| default | --scale-10 | 40px | text-sm font-medium leading-snug |
| lg | --scale-12 | 48px | text-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.
| Token | Where used |
|---|---|
--radius-full | Corner radius (circle) |
--scale-8 / --scale-10 / --scale-12 | Container size: sm / default / lg |
--muted | Fallback background |
--muted-foreground | Fallback 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: coverkeeps 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
alttext — 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-hiddenwhen adjacent text names the person. - No focus ring or
tabindex— Avatar isn’t interactive, so it stays out of the tab order. --muted-foregroundon--mutedis an existing Color pair that clears WCAG AA.