Avatar
An easily stylable avatar component.
import { Avatar } from 'base-ui-solid/avatar';
import styles from './index.module.css';
export default function ExampleAvatar() {
return (
<div style={{ display: 'flex', gap: '1rem' }}>
<Avatar.Root class={styles.Root}>
<Avatar.Image
src="https://images.unsplash.com/photo-1543610892-0b1f7e6d8ac1?w=128&h=128&dpr=2&q=80"
width="48"
height="48"
class={styles.Image}
/>
<Avatar.Fallback delay={600} class={styles.Fallback}>
LT
</Avatar.Fallback>
</Avatar.Root>
<Avatar.Root class={styles.Root}>LT</Avatar.Root>
</div>
);
}
Anatomy
Import the component and assemble its parts:
import { Avatar } from 'base-ui-solid/avatar';
<Avatar.Root>
<Avatar.Image src="" />
<Avatar.Fallback>LT</Avatar.Fallback>
</Avatar.Root>;
Optimized and lazy-loaded images
By default, <Avatar.Image> preloads src and renders the image only once it has loaded. This doesn’t compose with image optimizers that accept a Solid component, which serve a different URL than the raw src, or with loading="lazy".
Add the keepMounted prop to render the image element right away and let it load in place. Only the image that is actually displayed is requested:
// Image is a Solid-compatible image component supplied by your application.
<Avatar.Root>
<Avatar.Fallback>LT</Avatar.Fallback>
<Avatar.Image
keepMounted
render={(props) => <Image {...props} src="/avatar.png" width={32} height={32} alt="" />}
/>
</Avatar.Root>
Stacking
With keepMounted, the image and the fallback are both present until the image loads. The image is hidden from assistive technology until then, so the fallback provides the accessible name on its own.
Stack the two in the same box, and place <Avatar.Image> after <Avatar.Fallback>. Both are positioned, so whichever comes later in the DOM paints on top. The fallback then shows through until the image covers it.
A loading image paints nothing, so the fallback shows through on its own. An image that failed to load paints a broken-image icon on top of it. Hide the image in either state with the data-loading and data-error attributes:
.Root {
position: relative;
}
.Image,
.Fallback {
position: absolute;
inset: 0;
}
.Image[data-loading],
.Image[data-error] {
visibility: hidden;
}
Avoid display: none here: an element without a box never intersects the viewport, so loading="lazy" would never fetch the image. visibility and opacity both keep lazy loading working.
Server rendering
With keepMounted, the image is part of the server-rendered HTML and starts loading before hydration. So is the fallback, which stays visible until hydration resolves the loading status. A cached image is displayed immediately, without an enter animation.
API reference
Root
Displays a user’s profile picture, initials, or fallback icon.
Renders a <span> element.
classfunction—
JSX.ClassValue | ((state) => JSX.ClassValue)stylefunction—
JSX.CSSProperties | string | ((state) => JSX.CSSProperties | string | undefined)renderfunction—
keyof JSX.IntrinsicElements | Component | ((props, state) => JSX.Element)Root.State
type AvatarRootState = {
/** The image loading status. */
imageLoadingStatus: ImageLoadingStatus;
};Image
The image to be displayed in the avatar.
Renders an <img> element.
onLoadingStatusChangefunction—
((status: ImageLoadingStatus) => void)classfunction—
JSX.ClassValue | ((state) => JSX.ClassValue)stylefunction—
JSX.CSSProperties | string | ((state) => JSX.CSSProperties | string | undefined)keepMountedbooleanfalse
loading="lazy" and optimized image components such as next/image.booleanrenderfunction—
keyof JSX.IntrinsicElements | Component | ((props, state) => JSX.Element)Data attributes
data-error-—
-data-loading-—
-data-starting-style-—
-data-ending-style-—
-Attribute | Description | |
|---|---|---|
data-error | Present when the image failed to load. | |
data-loading | Present while the image is loading. | |
data-starting-style | Present when the image begins animating in. | |
data-ending-style | Present when the image is animating out. | |
Image.State
type AvatarImageState = {
/** The transition status of the component. */
transitionStatus: TransitionStatus;
/** The image loading status. */
imageLoadingStatus: ImageLoadingStatus;
};Fallback
Rendered when the image fails to load or when no image is provided.
Renders a <span> element.
delaynumber0
numberclassfunction—
JSX.ClassValue | ((state) => JSX.ClassValue)stylefunction—
JSX.CSSProperties | string | ((state) => JSX.CSSProperties | string | undefined)renderfunction—
keyof JSX.IntrinsicElements | Component | ((props, state) => JSX.Element)Fallback.State
type AvatarFallbackState = {
/** The image loading status. */
imageLoadingStatus: ImageLoadingStatus;
};Additional types
ImageLoadingStatus
type ImageLoadingStatus = 'idle' | 'loading' | 'loaded' | 'error';