# Avatar (/docs/avatar)





## API Reference [#api-reference]

<BaseUIReference href="https://base-ui.com/react/components/avatar" />

## Basic [#basic]

<Preview cssProperties="avatarPlaygroundCssProperties">
  <AvatarExample />

  <Preview.Code>
    {`
          import { Avatar, AvatarImage, AvatarFallback } from "moduix";

          export function AvatarDemo() {
            return (
              <Avatar>
                <AvatarImage src={avatarImage} alt="Alex T." />
                <AvatarFallback delay={600}>LT</AvatarFallback>
              </Avatar>
            );
          }
        `}
  </Preview.Code>

  <Preview.Data>
    {`
          const avatarImage =
            "https://images.unsplash.com/photo-1543610892-0b1f7e6d8ac1?w=128&h=128&dpr=2&q=80";
        `}
  </Preview.Data>

  <Preview.CSSProperties>
    {(context) => <AvatarCssPropertiesPanel {...context} />}
  </Preview.CSSProperties>

  <Preview.CSSPlayground>
    {(context) => <AvatarCssPlaygroundPanel {...context} />}
  </Preview.CSSPlayground>
</Preview>

## Anatomy [#anatomy]

`Avatar` is composed as one root with two content slots. Keep `AvatarImage` and `AvatarFallback`
inside the same `Avatar` so loading state, error state, and fallback timing stay synchronized.

```text
Avatar
├─ AvatarImage
└─ AvatarFallback
   └─ initials | icon | custom content
```

```tsx
<Avatar>
  <AvatarImage src={avatarImage} alt="Alex T." />
  <AvatarFallback delay={600}>LT</AvatarFallback>
</Avatar>
```

| Part             | Role                                                                                      |
| ---------------- | ----------------------------------------------------------------------------------------- |
| `Avatar`         | Root slot. Controls size, shape, inherited styles, and composition with `render`.         |
| `AvatarImage`    | Image slot. Renders the visual identity when the `src` is loaded successfully.            |
| `AvatarFallback` | Fallback slot. Renders initials, icon, or custom content while loading or on image error. |

`Avatar` does not use service slots such as `portal`, `backdrop`, or `viewport`.
In most cases, keep default behavior and style visible slots with `className` and CSS variables.

## Composition [#composition]

Use `className` on `Avatar`, `AvatarImage`, and `AvatarFallback`. Like Base UI, each slot also
accepts state-based `className` and `style` functions plus `render` for element composition.
Use `AvatarImage onLoadingStatusChange` when application logic needs the image load state, and
`AvatarFallback delay` when you want to avoid a fallback flash during normal image loading.

## Examples [#examples]

### Fallback Only [#fallback-only]

Render initials or short text directly inside `AvatarFallback` when no image is available. Use
the `size` prop to switch between the built-in `xs`, `sm`, `md`, `lg`, and `xl` sizes.

<Preview>
  <AvatarFallbackOnlyExample />

  <Preview.Code>
    {`
          import { Avatar, AvatarFallback } from "moduix";

          export function AvatarFallbackOnlyDemo() {
            return (
              <div className={styles.row}>
                {sizes.map((size) => (
                  <Avatar key={size} size={size}>
                    <AvatarFallback>{size.toUpperCase()}</AvatarFallback>
                  </Avatar>
                ))}
              </div>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .row {
            display: flex;
            align-items: center;
            gap: var(--spacing-3);
          }
        `}
  </Preview.CSS>

  <Preview.Data>
    {`
          const sizes = ["xs", "sm", "md", "lg", "xl"] as const;
        `}
  </Preview.Data>
</Preview>

### Render Composition [#render-composition]

`Avatar`, `AvatarImage`, and `AvatarFallback` are all public slots. Use `className` on each
slot, and use Base UI's `render` prop when the root should compose with another element.

<Preview>
  <AvatarCompositionExample />

  <Preview.Code>
    {`
          import { Avatar, AvatarImage, AvatarFallback } from "moduix";

          export function AvatarCompositionDemo() {
            return (
              <Avatar render={<a href="mailto:alex@example.com" />} className={styles.compositionRoot}>
                <AvatarImage className={styles.compositionImage} src={avatarImage} alt="Alex T." />
                <AvatarFallback className={styles.compositionFallback} delay={600}>
                  LT
                </AvatarFallback>
              </Avatar>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .compositionRoot {
            --avatar-size: var(--size-xl);

            text-decoration: none;
            transition:
              box-shadow var(--transition-default),
              transform var(--transition-default);
          }

          .compositionRoot:hover {
            box-shadow:
              0 0 0 2px var(--color-background),
              0 0 0 4px var(--color-primary);
            transform: translateY(-1px);
          }

          .compositionImage {
            object-position: 50% 35%;
          }

          .compositionFallback {
            --avatar-fallback-bg: var(--color-primary);
            --avatar-fallback-color: var(--color-primary-foreground);
          }
        `}
  </Preview.CSS>

  <Preview.Data>
    {`
          const avatarImage =
            "https://images.unsplash.com/photo-1543610892-0b1f7e6d8ac1?w=128&h=128&dpr=2&q=80";
        `}
  </Preview.Data>
</Preview>

### Image Error [#image-error]

Keep a fallback in the composition so the avatar stays meaningful when the image fails to load.

<Preview>
  <AvatarImageErrorExample />

  <Preview.Code>
    {`
          import { Avatar, AvatarImage, AvatarFallback } from "moduix";

          export function AvatarImageErrorDemo() {
            return (
              <Avatar>
                <AvatarImage src="https://example.com/does-not-exist.png" alt="Broken image example" />
                <AvatarFallback>NA</AvatarFallback>
              </Avatar>
            );
          }
        `}
  </Preview.Code>
</Preview>

### Custom Styles [#custom-styles]

Pass `className` to the root, image, and fallback slots when styling with CSS Modules, Tailwind CSS, or CSS-in-JS.

<Preview>
  <CustomStylesAvatarExample />

  <Preview.Code>
    {`
          import { Avatar, AvatarImage, AvatarFallback } from "moduix";

          export function CustomStylesAvatarDemo() {
            return (
              <Avatar size="lg" className={styles.ring}>
                <AvatarImage className={styles.imageSaturated} src={avatarImage} alt="Alex T." />
                <AvatarFallback className={styles.uppercase}>LT</AvatarFallback>
              </Avatar>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .ring {
            box-shadow:
              0 0 0 2px var(--color-background),
              0 0 0 4px var(--color-ring);
          }

          .imageSaturated {
            filter: saturate(1.5);
          }

          .uppercase {
            text-transform: uppercase;
          }
        `}
  </Preview.CSS>

  <Preview.Data>
    {`
          const avatarImage =
            "https://images.unsplash.com/photo-1543610892-0b1f7e6d8ac1?w=128&h=128&dpr=2&q=80";
        `}
  </Preview.Data>
</Preview>

### Fallback Icon [#fallback-icon]

Pass any React node to `AvatarFallback` to use an icon from your application or icon library.

<Preview>
  <AvatarCustomFallbackExample />

  <Preview.Code>
    {`
          import { Avatar, AvatarFallback, ComputerIcon } from "moduix";

          export function AvatarCustomFallbackDemo() {
            return (
              <Avatar size="lg" className={styles.customFallbackAvatar}>
                <AvatarFallback>
                  <ComputerIcon className={styles.customFallbackIcon} />
                </AvatarFallback>
              </Avatar>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .customFallbackAvatar {
            --avatar-bg: var(--color-accent);
            --avatar-fallback-color: var(--color-accent-foreground);
          }

          .customFallbackIcon {
            width: 55%;
            height: 55%;
          }
        `}
  </Preview.CSS>
</Preview>
