---
title: Avatar
description: Circular user or entity avatar with fallback initials and an optional indicator.
sidebar:
  order: 4
search:
  tags: [profile, image, fallback, user]
---

# Avatar

> Circular user or entity avatar with fallback initials and an optional indicator.

## Import

```tsx
import { Avatar } from 'moraine'
```

## Slot Structure

Avatar renders a single image/fallback frame. Use [`AvatarGroup`](https://ui.subf.dev/avatar-group.md) for grouped avatars with an overflow counter.

### Single avatar

```text
root
├── image
├── fallback
│   └── fallbackIcon (Icon, optional)
└── badge (optional)
```

## Examples

### Single Avatar

Fallback first, then image crossfades in after preload.

```tsx
function SingleAvatar() {
  const IMAGE_A = createSvgDataUrl('A', '#3f3f46')

  const IMAGE_B = createSvgDataUrl('B', '#18181b')

  const [source, setSource] = createSignal(IMAGE_A)

  function createSvgDataUrl(label: string, backgroundColor: string): string {
    const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" fill="${backgroundColor}"/><text x="32" y="38" text-anchor="middle" fill="white" font-family="sans-serif" font-size="24">${label}</text></svg>`
    return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`
  }

  return (
    <div class="flex gap-4 items-center">
      <Avatar
        src={source()}
        alt="Moraine"
        classes={{
          root: 'ring-ring',
        }}
      />

      <Button
        variant="outline"
        onClick={() => {
          setSource((current) => (current === IMAGE_A ? IMAGE_B : IMAGE_A))
        }}
      >
        Swap Source
      </Button>
    </div>
  )
}
```

### Sizes

Scale single avatars from `xs` to `xl`.

```tsx
function Sizes() {
  const SIZES: AvatarSize[] = ['xs', 'sm', 'md', 'lg', 'xl']

  return (
    <div class="flex flex-wrap gap-4 items-end">
      <For each={SIZES}>
        {(size) => (
          <div class="flex flex-col gap-2 items-center">
            <Avatar size={size} text="MR" />
            <span class="text-xs text-muted-foreground font-mono">{size}</span>
          </div>
        )}
      </For>
    </div>
  )
}
```

### Fallback Modes

Text, initials-from-alt and fallback icon.

```tsx
function FallbackModes() {
  return (
    <div class="flex flex-wrap gap-3 items-center">
      <Avatar text="MR" />
      <Avatar alt="Moraine Team" />
      <Avatar fallback="i-lucide-user" />
    </div>
  )
}
```

### Badge Positions

Top/bottom + left/right corner badge.

```tsx
function BadgePositions() {
  return (
    <div class="flex flex-wrap gap-3 items-center">
      <Avatar text="A" badge="i-lucide-check" badgePosition="top-left" />
      <Avatar text="B" badge="i-lucide-check" badgePosition="top-right" />
      <Avatar text="C" badge="i-lucide-check" badgePosition="bottom-left" />
      <Avatar text="D" badge="i-lucide-check" badgePosition="bottom-right" />
    </div>
  )
}
```

## API Reference

### Attributes

#### `root`

Avatar frame that controls size, shape, image, fallback, and badge placement.

#### `image`

Loaded avatar image rendered inside the frame.

#### `fallback`

Text fallback shown while the image is unavailable or failed.

#### `fallbackIcon`

Icon fallback shown when no image or text fallback is available.

#### `badge`

Status or indicator badge anchored to the avatar frame.

### Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| alt | string \| undefined | — | Accessible alt text for the avatar. |
| badge | IconT.Name | — | Icon name for the badge. |
| badgePosition | "top-left" \| "top-right" \| "bottom-left" \| "bottom-right" \| undefined | bottom-right | Position of the badge. |
| class | ClassValue | — | Class applied to the component root or trigger element. |
| classes | AvatarT.Classes \| undefined | — | — |
| fallback | IconT.Name | — | Icon name to show as fallback. |
| onStatusChange | ((status: AvatarStatus) => void) \| undefined | — | Callback when the loading status of the avatar changes. |
| ref | JSX.HTMLElementTags["span"] extends { ref?: infer Ref; } ? Ref : never \| undefined | — | — |
| size | "xs" \| "sm" \| "md" \| "lg" \| "xl" \| undefined | — | — |
| src | string \| undefined | — | Source URL for the avatar image. |
| style | JSX.CSSProperties \| undefined | — | — |
| styles | AvatarT.Styles \| undefined | — | — |
| text | string \| undefined | — | Initial text to show if image fails or is missing. |
| transition | "none" \| "fast" \| "normal" \| "slow" \| undefined | — | — |

### Items

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| alt | string \| undefined | — | Accessible alt text for the avatar. |
| badge | IconT.Name | — | Icon name for the badge. |
| badgePosition | NonNullable<"top-left" \| "top-right" \| "bottom-left" \| "bottom-right" \| undefined> \| undefined | bottom-right | Position of the badge. |
| fallback | IconT.Name | — | Icon name to show as fallback. |
| onStatusChange | ((status: AvatarStatus) => void) \| undefined | — | Callback when the loading status of the avatar changes. |
| src | string \| undefined | — | Source URL for the avatar image. |
| text | string \| undefined | — | Initial text to show if image fails or is missing. |

### ARIA

Accessibility attributes and roles emitted by the component markup.

| Attribute | Type | Description |
| --- | --- | --- |
| aria-hidden | boolean \| string \| undefined | Hides decorative content from assistive technology. |

### Data Attributes

State and slot attributes exposed for styling hooks and selectors.

| Attribute | Type | Description |
| --- | --- | --- |
| data-slot | string | Identifies the rendered slot for styling hooks and selectors. |
| data-status | string \| undefined | Stores async loading, loaded, or error status. |
