Avatar
A circular portrait that falls back to initials or a glyph while the image loads or when it fails.
Avatar shows a person or an account as a circle, with an image that fills it and a fallback for
initials or a glyph. It wraps Radix Avatar, so the fallback is on screen until the image has
loaded and stays there if the image fails, and size sets the circle and the initials together.
Usage
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
<Avatar>
<AvatarImage src="/me.jpg" alt="Jordan Kim" />
<AvatarFallback>JK</AvatarFallback>
</Avatar>The fallback stands in for the image
AvatarImage renders its <img> only once the file has loaded, so nothing is drawn for a
missing, blocked, or slow image except the fallback. AvatarFallback fills the circle with
bg-surface-sunken and sets its content in text-fg-muted, which suits initials or a small
icon. Leave AvatarImage out to show the fallback alone, as the third avatar above does.
Add delayMs to AvatarFallback to hold it back for that many milliseconds, so a fast image
does not flash the initials first. The fallback is a fixed 14px at md and 12px at sm and xs,
so keep it to a short run of letters, and use one letter at xs.
An image that is not square is cropped to the circle with object-cover, centered, rather
than stretched.
Three sizes
xs is 20px, sm is 32px, and md is 40px and the default. The step travels to the fallback
through a data-size attribute on the root, so the initials shrink with the circle. Setting a
size class on the root alone, like className="size-8", resizes the circle and leaves the initials
at the md size, so use size instead.
Beside a name
An image with a name beside it repeats that name to a screen reader. Give the image alt="" and
the fallback aria-hidden when the name is on screen, and give it the person's name as alt when
the avatar stands alone. The second avatar below has no text next to it, so its image carries the
name.
Props
Avatar takes every Radix Avatar Root attribute, plus this.
| Prop | Type | Default | What it does |
|---|---|---|---|
size | "xs" | "sm" | "md" | "md" | Sets the circle to 20, 32, or 40px and the fallback text to match. |
AvatarImage and AvatarFallback are as on Radix Avatar, so AvatarImage takes onLoadingStatusChange
and AvatarFallback takes delayMs. The AvatarSize type is exported.
Accessibility
- The avatar is a plain
<span>with no role, and it takes no focus. If it is clickable, put it inside a button or a link that has a name. - The image is named by its
alt, which Avatar does not require. An image with noaltis read by some screen readers by its file name, so always pass one, and passalt=""when the name is already on screen. - The fallback is text, so a screen reader reads "JK" as letters unless you set
aria-hiddenon it. Hide it when a name sits next to it, and leave it readable when it is the only label. - No color carries meaning, because the image or the initials identify the person.
- Avatar sets no forced-colors rules. The fallback fill is a background, which Windows high
contrast replaces, so the initials stay readable but the circle can read as plain text. The
contrast of
text-fg-mutedonbg-surface-sunkenis not checked here. - Avatar has no transitions or motion.
When to use something else
- Badge for a read-only status or count, and Chip for a removable value. An avatar identifies a person and is not a label.
- Category colors when the mark stands for a
value that keeps its own hue, like a priority or a status, through
CategoryTag. An avatar's fallback is always the neutral sunken fill. - Item for a row that pairs an avatar with a title and a
description. Put the avatar in
ItemMedia.
Install
shadcn add @gesso/avatar