Avatar
Display user profile images with customizable fallback content
Import
import { AvAvatarImports } from '@avesra/angular';Usage
import { Component } from '@angular/core';
import { AvAvatarImports } from '@avesra/angular';
@Component({
selector: 'app-avatar-basic-demo',
imports: [AvAvatarImports],
template: `<div class="flex items-center gap-4">
<span av-avatar>
<img
av-avatar-image
alt="John Doe"
src="/images/avatars/avatar-man-glasses-salt-pepper.png"
/>
<span av-avatar-fallback>JD</span>
</span>
<span av-avatar>
<img
av-avatar-image
alt="Blue"
src="/images/avatars/avatar-boy-smiling-blue-shirt.png"
/>
<span av-avatar-fallback>B</span>
</span>
<span av-avatar>
<span av-avatar-fallback>JR</span>
</span>
</div>`,
})
export class AvatarBasicDemo {}Anatomy
Compose span[av-avatar] with optional img[av-avatar-image] and span[av-avatar-fallback]. The image is a native img host, so standard attributes like src, alt, srcset, and loading work directly.
<span av-avatar>
<img av-avatar-image />
<span av-avatar-fallback></span>
</span>Sizes
import { Component } from '@angular/core';
import { AvAvatarImports } from '@avesra/angular';
@Component({
selector: 'app-avatar-sizes-demo',
imports: [AvAvatarImports],
template: `<div class="flex items-center gap-4">
<span av-avatar size="sm">
<img
av-avatar-image
alt="Small Avatar"
src="/images/avatars/avatar-boy-smiling-blue-shirt.png"
/>
<span av-avatar-fallback>SM</span>
</span>
<span av-avatar size="md">
<img
av-avatar-image
alt="Medium Avatar"
src="/images/avatars/avatar-woman-grey-hair-smiling.png"
/>
<span av-avatar-fallback>MD</span>
</span>
<span av-avatar size="lg">
<img
av-avatar-image
alt="Large Avatar"
src="/images/avatars/avatar-woman-glasses-auburn-hair.png"
/>
<span av-avatar-fallback>LG</span>
</span>
</div>`,
})
export class AvatarSizesDemo {}Colors
import { Component } from '@angular/core';
import { AvAvatarImports } from '@avesra/angular';
@Component({
selector: 'app-avatar-with-colors-demo',
imports: [AvAvatarImports],
template: `<div class="flex items-center gap-4">
<span av-avatar color="default">
<span av-avatar-fallback>DF</span>
</span>
<span av-avatar color="accent">
<span av-avatar-fallback>AC</span>
</span>
<span av-avatar color="success">
<span av-avatar-fallback>SC</span>
</span>
<span av-avatar color="warning">
<span av-avatar-fallback>WR</span>
</span>
<span av-avatar color="danger">
<span av-avatar-fallback>DG</span>
</span>
</div>`,
})
export class AvatarWithColorsDemo {}Variants
import { Component } from '@angular/core';
import {
AvAvatarImports,
AvSeparatorImports,
} from '@avesra/angular';
import type { AvAvatarColor } from '@avesra/angular';
import { AppIconComponent } from '../../components/app-icon/app-icon.component';
@Component({
selector: 'app-avatar-variants-demo',
imports: [
AppIconComponent,
AvAvatarImports,
AvSeparatorImports,
],
template: `<div class="flex flex-col gap-4">
<div class="flex items-center gap-3">
<div class="w-24 shrink-0"></div>
@for (color of colors; track color) {
<div class="flex w-20 shrink-0 items-center justify-center">
<span class="text-xs text-muted capitalize">{{ color }}</span>
</div>
}
</div>
<hr av-separator />
@for (variant of variants; track variant.label) {
<div class="flex items-center gap-3">
<div class="w-24 shrink-0 text-sm text-muted">{{ variant.label }}</div>
@for (color of colors; track color; let i = $index) {
<div class="flex w-20 shrink-0 items-center justify-center">
<span
av-avatar
[color]="color"
[variant]="isSoft(variant.type) ? 'soft' : 'default'"
>
@if (variant.type === 'img') {
<img
av-avatar-image
[alt]="'Avatar ' + color"
[src]="avatarImages[i]"
/>
<span av-avatar-fallback>{{ color.charAt(0).toUpperCase() }}</span>
} @else if (isIcon(variant.type)) {
<span av-avatar-fallback>
<app-icon icon="solar:user-linear" size="16" />
</span>
} @else {
<span av-avatar-fallback>{{ variant.content }}</span>
}
</span>
</div>
}
</div>
}
</div>`,
})
export class AvatarVariantsDemo {
readonly colors: readonly AvAvatarColor[] = [
'accent',
'default',
'success',
'warning',
'danger',
];
readonly avatarImages = ["/images/avatars/avatar-man-glasses-salt-pepper.png","/images/avatars/avatar-woman-grey-hair-smiling.png","/images/avatars/avatar-girl-smiling-blue-dress.png","/images/avatars/avatar-boy-smiling-blue-shirt.png","/images/avatars/avatar-woman-glasses-auburn-hair.png"];
readonly variants: readonly {
label: string;
type: 'letter' | 'letter-soft' | 'icon' | 'icon-soft' | 'img';
content?: string;
}[] = [
{ label: 'letter', type: 'letter', content: 'AG' },
{ label: 'letter soft', type: 'letter-soft', content: 'AG' },
{ label: 'icon', type: 'icon' },
{ label: 'icon soft', type: 'icon-soft' },
{ label: 'img', type: 'img' },
];
isSoft(type: string): boolean {
return type.includes('soft');
}
isIcon(type: string): boolean {
return type === 'icon' || type === 'icon-soft';
}
}Fallback Content
NA GB import { Component } from '@angular/core';
import { AvAvatarImports } from '@avesra/angular';
import { AppIconComponent } from '../../components/app-icon/app-icon.component';
@Component({
selector: 'app-avatar-fallback-demo',
imports: [
AppIconComponent,
AvAvatarImports,
],
template: `<div class="flex items-center gap-4">
<span av-avatar>
<span av-avatar-fallback>JD</span>
</span>
<span av-avatar>
<span av-avatar-fallback>
<app-icon icon="solar:user-linear" size="16" />
</span>
</span>
<span av-avatar>
<img
av-avatar-image
alt="Delayed Avatar"
src="https://invalid-url-to-show-fallback.com/image.jpg"
/>
<span av-avatar-fallback [delay-ms]="600">NA</span>
</span>
<span av-avatar>
<span
av-avatar-fallback
class="border-none bg-gradient-to-br from-pink-500 to-purple-500 text-white"
>
GB
</span>
</span>
</div>`,
})
export class AvatarFallbackDemo {}Avatar Group
import { Component } from '@angular/core';
import { AvAvatarImports } from '@avesra/angular';
@Component({
selector: 'app-avatar-group-demo',
imports: [AvAvatarImports],
template: `<div class="flex flex-col gap-6">
<div class="flex -space-x-2">
@for (user of basicUsers; track user.id) {
<span av-avatar class="ring-2 ring-background">
<img av-avatar-image [alt]="user.name" [src]="user.image" />
<span av-avatar-fallback>{{ initials(user.name) }}</span>
</span>
}
</div>
<div class="flex -space-x-2">
@for (user of counterUsers; track user.id) {
<span av-avatar class="ring-2 ring-background">
<img av-avatar-image [alt]="user.name" [src]="user.image" />
<span av-avatar-fallback>{{ initials(user.name) }}</span>
</span>
}
<span av-avatar class="ring-2 ring-background">
<span av-avatar-fallback class="text-xs">+{{ overflowCount }}</span>
</span>
</div>
</div>`,
})
export class AvatarGroupDemo {
readonly users = [
{
"id": 1,
"image": "/images/avatars/avatar-man-glasses-salt-pepper.png",
"name": "John Doe"
},
{
"id": 2,
"image": "/images/avatars/avatar-woman-grey-hair-smiling.png",
"name": "Kate Wilson"
},
{
"id": 3,
"image": "/images/avatars/avatar-girl-smiling-blue-dress.png",
"name": "Emily Chen"
},
{
"id": 4,
"image": "/images/avatars/avatar-boy-smiling-blue-shirt.png",
"name": "Michael Brown"
},
{
"id": 5,
"image": "/images/avatars/avatar-woman-glasses-auburn-hair.png",
"name": "Olivia Davis"
}
];
readonly basicUsers = this.users.slice(0, 4);
readonly counterUsers = this.users.slice(0, 3);
readonly overflowCount = this.users.length - 3;
initials(name: string): string {
return name
.split(' ')
.map((part) => part[0])
.join('');
}
}Styling
Passing Tailwind CSS classes
Pass utility classes on the avatar host and its parts to customize size, shape, and decoration.
import { Component } from '@angular/core';
import { AvAvatarImports } from '@avesra/angular';
@Component({
selector: 'app-avatar-custom-styles-demo',
imports: [AvAvatarImports],
template: `<div class="flex items-center gap-4">
<span av-avatar class="size-16">
<img
av-avatar-image
alt="Extra Large"
src="/images/avatars/avatar-boy-smiling-blue-shirt.png"
/>
<span av-avatar-fallback>XL</span>
</span>
<span av-avatar class="rounded-lg">
<img
av-avatar-image
alt="Square Avatar"
src="/images/avatars/avatar-woman-grey-hair-smiling.png"
/>
<span av-avatar-fallback class="rounded-lg">SQ</span>
</span>
<span
av-avatar
class="bg-cover bg-center p-0.5"
[style.background-image]="'url(/images/gradients/gradient-warm-orange-yellow-red.png)'"
>
<div class="size-full rounded-full bg-background p-0.5">
<img
av-avatar-image
class="rounded-full"
alt="Gradient Border"
src="/images/avatars/avatar-woman-glasses-auburn-hair.png"
/>
<span av-avatar-fallback class="border-none">GB</span>
</div>
</span>
<div class="relative">
<span av-avatar>
<img
av-avatar-image
alt="Online User"
src="/images/avatars/avatar-man-glasses-salt-pepper.png"
/>
<span av-avatar-fallback>ON</span>
</span>
<span
class="absolute right-0 bottom-0 size-3 rounded-full bg-green-500 ring-2 ring-background"
></span>
</div>
</div>`,
})
export class AvatarCustomStylesDemo {}Customizing the component classes
To customize the Avatar classes, use the @layer components directive. Learn more.
@layer components {
.av-avatar {
@apply size-16 border-2 border-accent;
}
.av-avatar__fallback {
@apply bg-linear-to-br from-purple-500 to-pink-500;
}
}Avesra follows the BEM methodology so component variants and states stay reusable and easy to customize.
CSS Classes
The Avatar component uses these CSS classes:
Base Classes
.av-avatar— Base container with default size (size-10).av-avatar__image— Image element with aspect-square sizing.av-avatar__fallback— Fallback container with centered content
Size Modifiers
.av-avatar--sm— Small avatar (size-8).av-avatar--md— Medium avatar (default, no additional styles).av-avatar--lg— Large avatar (size-12)
Variant Modifiers
.av-avatar--soft— Soft variant with lighter background
Color Modifiers
.av-avatar__fallback--default— Default text color.av-avatar__fallback--accent— Accent text color.av-avatar__fallback--success— Success text color.av-avatar__fallback--warning— Warning text color.av-avatar__fallback--danger— Danger text color
API Reference
Root options live on span[av-avatar]. Image attributes bind on img[av-avatar-image]; fallback options on span[av-avatar-fallback].
| Prop | Type | Default | Description |
|---|---|---|---|
color | 'default' | 'accent' | 'success' | 'warning' | 'danger' | 'default' | Fallback color theme (span[av-avatar]). |
size | 'sm' | 'md' | 'lg' | 'md' | Avatar size (span[av-avatar]). |
variant | 'default' | 'soft' | 'default' | Visual style variant (span[av-avatar]). |
src | string | — | Image source URL (img[av-avatar-image]). |
srcset | string | — | Responsive image `srcset` (img[av-avatar-image]). |
sizes | string | — | Responsive image `sizes` hint (img[av-avatar-image]). |
alt | string | — | Accessible alternative text (img[av-avatar-image]). |
crossorigin | 'anonymous' | 'use-credentials' | — | CORS setting for the image request (img[av-avatar-image]). |
loading | 'eager' | 'lazy' | — | Native lazy loading attribute (img[av-avatar-image]). |
delay-ms | number | 0 | Delay before showing fallback while the image loads (span[av-avatar-fallback]). |
color | 'default' | 'accent' | 'success' | 'warning' | 'danger' | undefined | — | Override color from parent. Inherits from av-avatar when omitted (span[av-avatar-fallback]). |