Skip to content

Avatar

  • A person’s picture next to their name, in comments, lists and headers
  • Initials or a placeholder when there is no picture, or it fails to load
  • A stack of people on a shared item

Not for logos or general images — use a plain <img>.

import { Avatar } from '@arun-dev/ui';
// A tiny SVG stands in for a photo. The second fails to load and keeps its initials; the last
// fails too, and falls back to a placeholder picture instead.
const photo =
'data:image/svg+xml,' +
encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect width="40" height="40" fill="#7c3aed"/><circle cx="20" cy="16" r="7" fill="#ede9fe"/><rect x="8" y="26" width="24" height="14" rx="7" fill="#ede9fe"/></svg>',
);
// A generic silhouette, for people with no initials to show — or when you prefer a picture.
const placeholder =
'data:image/svg+xml,' +
encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect width="40" height="40" fill="#cbd5e1"/><circle cx="20" cy="16" r="7" fill="#f8fafc"/><rect x="8" y="26" width="24" height="14" rx="7" fill="#f8fafc"/></svg>',
);
export default function AvatarBasics() {
return (
<div style={{ display: 'flex', gap: 'var(--space-sm)', alignItems: 'center' }}>
<Avatar.Root>
<Avatar.Image src={photo} alt="Ada Lovelace" />
<Avatar.Fallback delay={300}>AL</Avatar.Fallback>
</Avatar.Root>
<Avatar.Root role="img" aria-label="Grace Hopper">
<Avatar.Image src="data:image/png;base64,broken" alt="Grace Hopper" />
<Avatar.Fallback aria-hidden="true">GH</Avatar.Fallback>
</Avatar.Root>
<Avatar.Root role="img" aria-label="Unknown user">
<Avatar.Image src="data:image/png;base64,broken" alt="" />
{/* Any content can be the fallback: here an image, filling the circle. */}
<Avatar.Fallback aria-hidden="true">
<img src={placeholder} alt="" style={{ inlineSize: '100%', blockSize: '100%' }} />
</Avatar.Fallback>
</Avatar.Root>
<Avatar.Root
role="img"
aria-label="Alan Turing"
style={{ ['--avatar-size' as string]: '3.5rem' }}
>
<Avatar.Fallback aria-hidden="true">AT</Avatar.Fallback>
</Avatar.Root>
</div>
);
}

Avatar shows a picture once it has loaded, and initials or an icon until then. If the picture fails, or there is none, the initials stay. A broken image never shows.

<Avatar.Root>
<Avatar.Image src={user.photo} alt={user.name} />
<Avatar.Fallback delay={300}>{initials}</Avatar.Fallback>
</Avatar.Root>
  • delay holds the initials back briefly, so a picture that loads fast doesn’t flash them first.
  • Initials are read out letter by letter. Give the Root role="img" and an aria-label with the name, and mark the initials aria-hidden. Or leave them be when the name is shown beside the avatar.
  • The fallback can hold anything: initials, an icon, or a placeholder picture, as the third avatar in the example shows. Make an image fill it with inline-size and block-size of 100%; the circle clips it. Use a local or inline image for it, so the fallback itself can’t fail to load.
  • Size it with --avatar-size.
Avatar.Fallback props
PropTypeDefaultDescription
delaynumber0Milliseconds before it shows, so a quick image does not flash the initials first.
classNamestringConcatenated with the component's own classes, never replacing them.
renderReactElementElement or component to render instead of the default. Props, className, event handlers and ref are merged onto it.
refRef<HTMLElement>Ref to the rendered element. Merged with any ref on the render element.
…restHTMLAttributesAnything else is spread onto the rendered element, so id, aria-*, data-* and event handlers all reach the DOM.

Avatar.Root and Avatar.Image take the props of the <span> and <img> they render.