bx

Avatar

An image element with a fallback for representing the user.

@shadcnCN@rabbitRBX
tsx
<Avatar>
  <AvatarImage src="/avatars/03.png" alt="@shadcn" />
  <AvatarFallback>CN</AvatarFallback>
</Avatar>

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> with aspect-square h-full w-full. If src fails 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

Terminal
$ bext ui add avatar

Usage

tsx
import { Avatar, AvatarImage, AvatarFallback, AvatarBadge, AvatarGroup } from "@bext-stack/ui/primitives"

// Simple avatar with image + initials fallback
<Avatar>
  <AvatarImage src="/avatars/03.png" alt="@shadcn" />
  <AvatarFallback>CN</AvatarFallback>
</Avatar>

// Avatar with a status badge
<Avatar>
  <AvatarImage src="/avatars/02.png" alt="@rabbit" />
  <AvatarFallback>R</AvatarFallback>
  <AvatarBadge className="bg-emerald-500" />
</Avatar>

// Group of 3 avatars + count
<AvatarGroup>
  <Avatar><AvatarImage src="/avatars/01.png" alt="Alice" /><AvatarFallback>A</AvatarFallback></Avatar>
  <Avatar><AvatarImage src="/avatars/02.png" alt="Bob" /><AvatarFallback>B</AvatarFallback></Avatar>
  <Avatar><AvatarImage src="/avatars/03.png" alt="Cassandra" /><AvatarFallback>C</AvatarFallback></Avatar>
  <AvatarGroupCount>+8</AvatarGroupCount>
</AvatarGroup>

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)

smSdefaultMlgL
tsx
<Avatar size="sm"><AvatarImage src="…" /><AvatarFallback>S</AvatarFallback></Avatar>
<Avatar><AvatarImage src="…" /><AvatarFallback>M</AvatarFallback></Avatar>
<Avatar size="lg"><AvatarImage src="…" /><AvatarFallback>L</AvatarFallback></Avatar>

Fallback (no image)

CNBXKZ
tsx
<Avatar>
  <AvatarFallback>CN</AvatarFallback>
</Avatar>

Badge (status overlay)

onlineObusyBofflineF
tsx
<Avatar>
  <AvatarImage src="…" alt="Alice" />
  <AvatarFallback>A</AvatarFallback>
  <AvatarBadge className="bg-emerald-500" />
</Avatar>

AvatarGroup (stacked)

AABBCC
+8
tsx
<AvatarGroup>
  <Avatar><AvatarImage src="…" alt="A" /><AvatarFallback>A</AvatarFallback></Avatar>
  <Avatar><AvatarImage src="…" alt="B" /><AvatarFallback>B</AvatarFallback></Avatar>
  <Avatar><AvatarImage src="…" alt="C" /><AvatarFallback>C</AvatarFallback></Avatar>
  <AvatarGroupCount>+8</AvatarGroupCount>
</AvatarGroup>
Try it live Open in play

Edit this example live in the bext playground. It compiles and runs entirely in your browser.

src/app/page.tsx 1 file · react · runs in your browser
The React idiom: same UI, for comparison.