Avatar
An image element with a fallback for representing the user.
Avatar represents a user or an identity: a round image with a text fallback (typically initials) shown while the image loads or if it fails. It is a purely visual component (not interactive on its own).
Composition:
- AvatarImage: the
<img>withaspect-square h-full w-full. Ifsrcfails to load, the browser shows the fallback underneath. - AvatarFallback: a
<span>that shows initials on a muted background. Visible only when the image has not loaded or has failed. - AvatarBadge: a status dot (typically online / offline) positioned absolutely at the bottom right. Sized according to the parent
size.
3 sizes: sm (h-6 w-6, 24px), default (h-8 w-8, 32px), lg (h-10 w-10, 40px). The size is stored as data-size on the root, which lets sub-components (Fallback, Badge) adapt via group-data-[size=…]/avatar:….
AvatarGroup stacks several Avatars with -space-x-2 and puts a ring-2 ring-background on each one (the overlapping look with a clean edge). Use AvatarGroupCount for the "+N" when only the first few are shown.
Installation
$ bext ui add avatar
Copy and paste the following into src/components/ui/avatar.tsx.
Usage
Anatomy
<Avatar size="sm|default|lg"> ├── <AvatarImage src="/…" alt="…" /> // image, loaded first ├── <AvatarFallback>CN</AvatarFallback> // initials if the image fails └── <AvatarBadge>...</AvatarBadge> // status dot, optional <AvatarGroup> // -space-x-2 + ring-2 ├── <Avatar>...</Avatar> ├── <Avatar>...</Avatar> └── <AvatarGroupCount>+3</AvatarGroupCount>
API Reference
Avatar
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "sm" | "default" | "lg" | "default" | Root size: sm=h-6 w-6, default=h-8 w-8, lg=h-10 w-10. Stored as data-size so it cascades to sub-components. |
| src | string | — | Shorthand (backwards-compat): when set without children, renders AvatarImage + AvatarFallback automatically. |
| fallback | string | — | Shorthand: initials shown via AvatarFallback when the src shorthand is used. |
| className | string | — | Additional CSS classes on the root . |
AvatarImage
| Prop | Type | Default | Description |
|---|---|---|---|
| src | string | — | Image URL (local or HTTP). |
| alt | string | "" | Alternative text. Always set it for a11y, using the user's name. |
| className | string | — | CSS classes. Default: aspect-square h-full w-full. |
AvatarFallback
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | CSS classes. Default: bg-muted text-sm text-muted-foreground. |
AvatarBadge
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | Status dot, absolute bottom-right. Sized from the parent's data-size. |
AvatarGroup
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | flex -space-x-2 with ring-2 ring-background on each child Avatar. |
AvatarGroupCount
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | "+N" bubble (same look as an Avatar) for the avatars that are not shown. |
Data Attributes
Attributes you can target in custom CSS to override the style for each state.
| Attribute | On | Values | Description |
|---|---|---|---|
| data-slot | every sub-component | "avatar" | "avatar-image" | "avatar-fallback" | "avatar-badge" | "avatar-group" | "avatar-group-count" | Stable selector for custom styling. |
| data-size | Avatar root | "sm" | "default" | "lg" | Cascades to Fallback (text-xs for sm) and Badge (h-2, h-2.5, h-3). |
Keyboard
| Key | Action |
|---|---|
| — | Avatar is not interactive by default. When wrapped in an <a> or <button>, Tab/Enter follow native behavior. |
Accessibility
Always set a descriptive alt on AvatarImage: it is what screen readers announce. Typical format: alt="@shadcn" or alt="Karim Zribi". Do not leave it empty unless the avatar is purely decorative (never the case in practice).
AvatarFallback is NOT an a11y fallback, it is visual only. Assistive technologies announce the alt of the AvatarImage even when the image fails to load.
AvatarBadge is visual only: add hidden text with <span class="sr-only">Online</span> so the status is announced.
In AvatarGroup, the avatars overlap visually. For a "+N" count, add aria-label="and N more" on the AvatarGroupCount.
Examples
Sizes (sm, default, lg)
Fallback (no image)
Badge (status overlay)
AvatarGroup (stacked)
Edit this example live in the bext playground. It compiles and runs entirely in your browser.
On This Page