Light

Avatar

An image element with a fallback for representing the user.

Spec · from metadata

When to use

  • Displaying user profile images
  • User identification in lists, comments, or navigation
  • Showing a group of avatars (e.g., team members, participants)
  • User status indicators via AvatarBadge

When not to use

  • Generic images — use a plain img tag
  • Logo display — use Logo component instead
  • Icon-only indicators — use Badge component instead

Variants

PropValuesDefaultDescription
sizedefaultsmlgdefaultControls avatar dimensions: sm=24px, default=32px, lg=40px.

Anti-patterns

Avoid<Avatar>
  <AvatarImage src="/user.jpg" />
</Avatar>
Prefer<Avatar>
  <AvatarImage src="/user.jpg" alt="John Doe" />
  <AvatarFallback>JD</AvatarFallback>
</Avatar>

Always include AvatarFallback for loading/error states, and alt text on AvatarImage.

Avoid<div className="flex -space-x-2">
  <Avatar>...</Avatar>
  <Avatar>...</Avatar>
</div>
Prefer<AvatarGroup>
  <Avatar>...</Avatar>
  <Avatar>...</Avatar>
  <AvatarGroupCount>+3</AvatarGroupCount>
</AvatarGroup>

Use AvatarGroup for proper ring styling and AvatarGroupCount for overflow.

Accessibility

  • Required ARIAalt on AvatarImage
  • Screen readerRadix Avatar handles image loading states. AvatarFallback shows for screen readers when image fails. AvatarBadge should include sr-only status text.
  • ContrastFallback uses bg-muted/text-muted-foreground. Badge uses bg-primary with ring-background border.

Token bindings

TokenCategoryUsage
mutedcolorFallback background
muted-foregroundcolorFallback text
primarycolorBadge background
backgroundcolorGroup ring color

Import

import { Avatar, AvatarFallback, AvatarImage } from "@timelycare/helix-ui"

Props

interface AvatarProps {
  className?: string
  children: React.ReactNode
}

interface AvatarImageProps {
  src: string
  alt: string
  className?: string
  onLoadingStatusChange?: (status: "loading" | "loaded" | "error") => void
}

interface AvatarFallbackProps {
  className?: string
  children: React.ReactNode  // Typically 1-2 character initials
  delayMs?: number           // Delay before showing fallback
}

Variants

VariantUse ForImplementation
ImageUser has profile picture<AvatarImage src="..." />
FallbackNo image or image fails<AvatarFallback>CN</AvatarFallback>

Shapes

ShapeDefaultUse ForCircle RadiusRounded Radius (size-dependent)
RoundedYesAll standard contexts: workspace, team, nav, appSee table below
CircleNoSocial media profiles, legacy circular UIs only — opt-in, not the defaultrounded-full

Rounded Shape Radius by Size

SizeRounded RadiusTailwind
12 (48px)16pxrounded-2xl
10 (40px)14pxrounded-xl
8 (32px)10pxrounded-lg
6 (24px)8pxrounded-md
5 (20px)6pxrounded-sm

Sizes

SizeDimensionsTailwindUse For
1248×48pxsize-12Profile headers, user cards
1040×40pxsize-10Navigation, dropdowns
832×32pxsize-8Comments, lists (default)
624×24pxsize-6Compact lists, mentions
520×20pxsize-5Inline, tags

Styling

Fallback

PropertyValue
Backgroundbg-accent (#e4eefa)
Borderborder border-accent-border (#c3dbf4)
Text Colortext-accent-foreground (#19518b)
Fontfont-sans (Adelle Sans Regular)
Text Aligntext-center

Fallback Text Size by Avatar Size

Avatar SizeFallback Text SizeLine Height
12 (48px)text-sm (14px)leading-5 (20px)
10 (40px)text-sm (14px)leading-5 (20px)
8 (32px)text-sm (14px)leading-5 (20px)
6 (24px)text-xs (12px)leading-4 (16px)
5 (20px)text-xs (12px)leading-4 (16px)

Image Loading State

PropertyValue
Backgroundbg-muted (#f4f4f5)

States

StateImplementation
ActiveBase appearance (default)
FocusBorder + ring shadow — scales with avatar size

Focus State by Size

SizeBorderRing SpreadRounded Radius (Rounded Shape)
12 (48px)border border-ringshadow-[0_0_0_3px]rounded-2xl (16px)
10 (40px)border-[0.833px] border-ringshadow-[0_0_0_2.5px]rounded-[13.333px]
8 (32px)border-[0.667px] border-ringshadow-[0_0_0_2px]rounded-[10.667px]
6 (24px)border-[0.5px] border-ringshadow-[0_0_0_1.5px]rounded-[8px]
5 (20px)border-[0.417px] border-ringshadow-[0_0_0_1.25px]rounded-[6.667px]

Focus ring color: ring (#a1a1aa) border with rgba(163,163,163,0.5) shadow. Simplified implementation uses ring-3 ring-ring for consistent focus styling.


Common Patterns

Basic with Fallback (Rounded — default)

<Avatar className="rounded-2xl">
  <AvatarImage src="/user.jpg" alt="@username" />
  <AvatarFallback>CN</AvatarFallback>
</Avatar>

Rounded Shape — All Sizes (size-dependent radius)

// Size 12 — rounded-2xl (16px)
<Avatar className="rounded-2xl">
  <AvatarImage src="/user.jpg" />
  <AvatarFallback>CN</AvatarFallback>
</Avatar>

// Size 10 — rounded-xl (14px)
<Avatar className="size-10 rounded-xl">
  <AvatarImage src="/user.jpg" />
  <AvatarFallback>CN</AvatarFallback>
</Avatar>

// Size 8 — rounded-lg (10px)
<Avatar className="size-8 rounded-lg">
  <AvatarImage src="/user.jpg" />
  <AvatarFallback className="text-sm">CN</AvatarFallback>
</Avatar>

// Size 6 — rounded-md (8px)
<Avatar className="size-6 rounded-md">
  <AvatarImage src="/user.jpg" />
  <AvatarFallback className="text-xs">CN</AvatarFallback>
</Avatar>

// Size 5 — rounded-sm (6px)
<Avatar className="size-5 rounded-sm">
  <AvatarImage src="/user.jpg" />
  <AvatarFallback className="text-xs">CN</AvatarFallback>
</Avatar>

Circle Shape — All Sizes

// Large (48px)
<Avatar className="size-12">
  <AvatarImage src="/user.jpg" />
  <AvatarFallback>CN</AvatarFallback>
</Avatar>

// Default (32px)
<Avatar className="size-8">
  <AvatarImage src="/user.jpg" />
  <AvatarFallback className="text-sm">CN</AvatarFallback>
</Avatar>

// Small (24px)
<Avatar className="size-6">
  <AvatarImage src="/user.jpg" />
  <AvatarFallback className="text-xs">CN</AvatarFallback>
</Avatar>

// Extra small (20px)
<Avatar className="size-5">
  <AvatarImage src="/user.jpg" />
  <AvatarFallback className="text-xs">CN</AvatarFallback>
</Avatar>

Fallback with Border

<Avatar>
  <AvatarFallback className="bg-accent text-accent-foreground border border-accent-border">
    CN
  </AvatarFallback>
</Avatar>

Avatar Group (Stacked)

<div className="flex items-center pr-2">
  <Avatar className="size-12 border-2 border-background -mr-2">
    <AvatarImage src="/user1.jpg" />
    <AvatarFallback>U1</AvatarFallback>
  </Avatar>
  <Avatar className="size-12 border-2 border-background -mr-2">
    <AvatarImage src="/user2.jpg" />
    <AvatarFallback>U2</AvatarFallback>
  </Avatar>
  <Avatar className="size-12 border-2 border-background -mr-2">
    <AvatarFallback className="bg-accent text-accent-foreground border border-accent-border">
      +3
    </AvatarFallback>
  </Avatar>
</div>

With User Info

<div className="flex items-center gap-3">
  <Avatar>
    <AvatarImage src="/user.jpg" />
    <AvatarFallback>JD</AvatarFallback>
  </Avatar>
  <div>
    <p className="text-sm font-medium">John Doe</p>
    <p className="text-xs text-muted-foreground">john@example.com</p>
  </div>
</div>

Component Structure

{/* Rounded shape variant — size 12 (default) */}
<div className="relative size-12 overflow-hidden rounded-2xl">
  
  {/* AvatarImage */}
  <img 
    src="/user.jpg" 
    alt="User" 
    className="absolute inset-0 size-full object-cover" 
  />
  
  {/* AvatarFallback (shown when image fails/loading) */}
  <div className="absolute inset-0 flex items-center justify-center bg-accent border border-accent-border text-sm text-accent-foreground">
    CN
  </div>
  
</div>

{/* Rounded shape variant — size 10 */}
<div className="relative size-10 overflow-hidden rounded-xl">
  ...
</div>

{/* Rounded shape variant — size 8 */}
<div className="relative size-8 overflow-hidden rounded-lg">
  ...
</div>

{/* Rounded shape variant — size 6 */}
<div className="relative size-6 overflow-hidden rounded-md">
  ...
</div>

{/* Rounded shape variant — size 5 */}
<div className="relative size-5 overflow-hidden rounded-sm">
  ...
</div>

{/* Circle shape variant */}
<div className="relative size-12 overflow-hidden rounded-full">
  ...
</div>

Accessibility

  • Built on Radix Avatar — presentational component
  • Provide meaningful alt text on AvatarImage
  • Fallback text is announced by screen readers
  • No keyboard interaction (non-interactive element)

Gotchas

ProblemSolution
Fallback shows briefly before imageUse delayMs prop on AvatarFallback
Small avatar text too bigUse text-xs for size-6 and size-5
Group avatars not overlappingUse -mr-2 on each avatar (negative right margin)
Group avatar borders blend inAdd border-2 border-background to each avatar
Focus ring not visibleEnsure ring token is defined
Rounded shape not correctUse size-dependent radius: rounded-2xl (12), rounded-xl (10), rounded-lg (8), rounded-md (6), rounded-sm (5)
Fallback missing borderAdd border border-accent-border to AvatarFallback
Circle shape used unintentionallyRounded is the default for all standard contexts. Circle is opt-in only — apply rounded-full explicitly when required for social/legacy interfaces.

See Also

  • Related Components: Hover Card (profile preview on hover), Badge (status indicator)
  • Tokens: Colors — Theme-aware color tokens

Last updated: February 20, 2026