Avatar
Description
Section titled “Description”.bp-avatar renders on a native <img> element. When the image loads, object-fit: cover crops it to a circle. When the image fails or src is empty, the browser renders the alt text — styled by the same flex layout — producing a CSS-only initials fallback with no JavaScript or extra markup. Size variants override a single --avatar-size token that drives width, height, and font-size together. .bp-avatar-group stacks multiple avatars with a negative overlap and a ring border for separation.
Single avatar with image
Section titled “Single avatar with image”With image
<img class="bp-avatar" src="https://i.pravatar.cc/80?img=1" alt="Jane Doe" width="40" height="40" />Initials fallback
Section titled “Initials fallback”When src is empty or the image fails to load, the browser renders alt text inside the styled flex container. Use one or two initials as the alt value.
Initials fallback (broken or empty src)
<img class="bp-avatar" src="" alt="JD" width="40" height="40" /><img class="bp-avatar" src="" alt="AL" width="40" height="40" /><img class="bp-avatar" src="" alt="MK" width="40" height="40" />Decorative (adjacent name visible)
Section titled “Decorative (adjacent name visible)”When the user’s name is visible in adjacent text, pass alt="" so screen readers skip the redundant image.
Decorative avatar alongside visible name
<style>.demo-avatar-identity { display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 600; }</style><div class="demo-avatar-identity"><img class="bp-avatar" src="https://i.pravatar.cc/80?img=2" alt="" width="40" height="40" />Jane Doe</div>All size variants override --avatar-size only. Font size scales automatically via calc().
Size variants
<style>.demo-avatar-sizes { display: inline-flex; align-items: center; gap: 1rem; }</style><div class="demo-avatar-sizes"><img class="bp-avatar bp-avatar--xs" src="" alt="XS" width="24" height="24" /><img class="bp-avatar bp-avatar--sm" src="" alt="SM" width="32" height="32" /><img class="bp-avatar" src="" alt="MD" width="40" height="40" /><img class="bp-avatar bp-avatar--lg" src="" alt="LG" width="48" height="48" /><img class="bp-avatar bp-avatar--xl" src="" alt="XL" width="64" height="64" /></div>Square shape
Section titled “Square shape”Square avatar
<img class="bp-avatar bp-avatar--square" src="https://i.pravatar.cc/80?img=3" alt="Team logo" width="40" height="40" />Avatar group with overflow
Section titled “Avatar group with overflow”Wrap avatars in .bp-avatar-group. Use role="group" and aria-label to give the group a collective name for screen readers. The overflow count avatar uses an intentionally empty src so the +N alt text always renders.
Avatar group with overflow count
<style>.demo-avatar-group-wrap { display: inline-flex; align-items: center; gap: 0.75rem; }</style><div class="demo-avatar-group-wrap"><div class="bp-avatar-group" role="group" aria-label="Project members"> <img class="bp-avatar" src="https://i.pravatar.cc/80?img=10" alt="Alice" width="40" height="40" /> <img class="bp-avatar" src="https://i.pravatar.cc/80?img=11" alt="Bob" width="40" height="40" /> <img class="bp-avatar" src="https://i.pravatar.cc/80?img=12" alt="Carol" width="40" height="40" /> <img class="bp-avatar bp-avatar--overflow" src="" alt="+3" width="40" height="40" /></div></div>Public API
Section titled “Public API”| Variable | Default | Description |
|---|---|---|
--avatar-size | 2.5rem | Width and height of the avatar |
--avatar-radius | 9999px | Border radius — 9999px produces a circle |
--avatar-font-size | calc(var(--avatar-size, 2.5rem) * 0.4) | Initials text size — scales with --avatar-size |
--avatar-font-weight | 600 | Initials text weight |
--avatar-bg | var(--bp-color-neutral-200, #e5e7eb) | Fallback background shown behind initials or on error |
--avatar-color | var(--bp-color-neutral-700, #374151) | Initials text color |
--avatar-border-width | 2px | Ring border width applied in groups |
--avatar-border-color | var(--bp-color-bg, #fff) | Ring border color — should match surrounding surface |
--avatar-group-overlap | -0.75rem | Negative margin-inline-start for stacking in groups |
--avatar-overflow-bg | var(--bp-color-neutral-300, #d1d5db) | Background for the +N overflow count avatar |
--avatar-overflow-color | var(--bp-color-neutral-800, #1f2937) | Text color for the +N overflow count avatar |
Size variant reference
Section titled “Size variant reference”| Class | --avatar-size |
|---|---|
bp-avatar--xs | 1.5rem |
bp-avatar--sm | 2rem |
| (default) | 2.5rem |
bp-avatar--lg | 3rem |
bp-avatar--xl | 4rem |
Customization
Section titled “Customization”Override public tokens via a scoped CSS class — never via style="".
Custom teal avatar with branded background
<style>.demo-avatar--brand { --avatar-bg: #0d9488; --avatar-color: #fff; --avatar-font-weight: 700;}.demo-avatar--tight-group { --avatar-group-overlap: -1.25rem; --avatar-border-color: #f0fdf4;}</style><img class="bp-avatar demo-avatar--brand" src="" alt="BP" width="40" height="40" />
<div class="bp-avatar-group demo-avatar--tight-group" role="group" aria-label="Tight group example"><img class="bp-avatar" src="https://i.pravatar.cc/80?img=20" alt="User one" width="40" height="40" /><img class="bp-avatar" src="https://i.pravatar.cc/80?img=21" alt="User two" width="40" height="40" /><img class="bp-avatar" src="https://i.pravatar.cc/80?img=22" alt="User three" width="40" height="40" /></div>Accessibility
Section titled “Accessibility”alt text rules
Section titled “alt text rules”| Scenario | alt value | Reason |
|---|---|---|
| Avatar is the sole identifier for the user | Full name — "Jane Doe" | Screen reader announces who the avatar represents |
| Adjacent visible text already names the user | "" (empty) | Avoids redundant announcement; image is decorative |
| Initials fallback | Initials — "JD" | Initials text renders visually and is the accessible name |
| Overflow count | Count — "+3" | Screen reader announces the count |
Groups
Section titled “Groups”Wrap avatar groups in role="group" with a descriptive aria-label (e.g. "Project members"). This groups the individual <img> labels together for screen readers without hiding any of them.
Decorative pattern
Section titled “Decorative pattern”alt="" marks an image as decorative. Use this when the user’s name appears as adjacent visible text — do not use it when the avatar is the only way to identify the person.
Browser APIs
Section titled “Browser APIs”| API | Availability | Used for | Without it | Polyfill |
|---|---|---|---|---|
object-fit | Widely available Baseline 2020 | Crops image to fill the avatar without distortion | Image may stretch or letterbox | None — widely supported |
alt text rendering (broken image) | Widely available Baseline 2020 | CSS-only initials fallback when src is empty or fails | No text displayed; background color remains | None needed — fallback degrades gracefully |
Safari variance: Safari may display a broken-image icon alongside the alt text when src is a non-empty URL that fails to load. When src="" (intentionally empty, as used for the overflow avatar and the initials pattern), Safari suppresses the broken-image icon and renders only the alt text — matching the intended design. For the initials fallback, always use src="" rather than a deliberately invalid URL.
Internals
Section titled “Internals”--_size,--_radius,--_font-size,--_font-weight,--_bg,--_color,--_border-width,--_border-color— component-private variables resolved on the root.bp-avatarselector. Do not set--_*variables directly.object-fit: coveris applied directly on.bp-avatar. When the image loads the browser respectsobject-fiton<img>. When it fails the flex layout takes over and centersalttext.- Size variants override
--avatar-sizeonly. The private--_font-sizerecomputes viacalc()automatically — no per-variant font-size override is needed. - Group stacking uses
isolation: isolateon.bp-avatar-groupto create a new stacking context, preventingz-indexleakage from surrounding content. - The
--overflowmodifier overrides--avatar-bgand--avatar-colorusing the public overflow tokens. It does not change structure — the element is still a plain.bp-avatar.