ProfilePicture
The core profile picture web component with extensive customization options
The <profile-picture> web component is the primary building block of the library. It renders an avatar image with support for shapes, borders, shadows, glows, rings, presence indicators, badges, fallbacks, loading states, and interactive behaviors.
This page documents the Web Component (HTML) usage. For the React wrapper with camelCase props and JSX syntax, see React ProfilePicture.
Basic Usage
<profile-pictureext-customer-id="demo-user-1769431807927-pd9dtmn1"alt="Kerry Nicholson"size="lg"variant="circle"></profile-picture>Core Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
src | string | — | Image source URL |
alt | string | '' | Alt text for accessibility |
ext-customer-id | string | — | External customer ID for CDN image loading |
image-mode | 'transparent' | 'original' | 'original' | CDN image mode |
When ext-customer-id is provided, the component fetches the image from the configured CDN instead of using src directly.
Sizing
| Attribute | Type | Default | Description |
|---|---|---|---|
size | Size | number | 'md' | Predefined size or custom pixel value |
Size Map
| Token | Pixels |
|---|---|
2xs | 20px |
xs | 24px |
sm | 32px |
md | 40px |
lg | 48px |
xl | 64px |
2xl | 80px |
3xl | 120px |
<!-- xs (24px) --><profile-picture ext-customer-id="demo-user-1769431807927-pd9dtmn1" alt="Kerry Nicholson" size="xs"></profile-picture><!-- md (40px) --><profile-picture ext-customer-id="demo-user-1769429613186-q8x65t0" alt="Sarah Chen" size="md"></profile-picture><!-- xl (64px) --><profile-picture ext-customer-id="demo-user-1769430228786-ompo3g1" alt="Emma Liu" size="xl"></profile-picture><!-- 3xl (120px) --><profile-picture ext-customer-id="demo-user-1769430441537-fs5i098" alt="Marcus Webb" size="3xl"></profile-picture>Visual
| Attribute | Type | Default | Description |
|---|---|---|---|
variant | 'circle' | 'rounded' | 'squircle' | 'square' | 'circle' | Shape variant |
shadow | 'none' | 'sm' | 'md' | 'lg' | 'glow' | 'sm' | Shadow preset |
<profile-picture ext-customer-id="demo-user-1769431807927-pd9dtmn1" alt="Kerry Nicholson" size="xl" variant="circle"></profile-picture><profile-picture ext-customer-id="demo-user-1769429613186-q8x65t0" alt="Sarah Chen" size="xl" variant="rounded"></profile-picture><profile-picture ext-customer-id="demo-user-1769430228786-ompo3g1" alt="Emma Liu" size="xl" variant="squircle"></profile-picture><profile-picture ext-customer-id="demo-user-1769430441537-fs5i098" alt="Marcus Webb" size="xl" variant="square"></profile-picture>Border
| Attribute | Type | Default | Description |
|---|---|---|---|
border | boolean | false | Enable border |
border-width | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 2 | Border width in pixels |
border-color | string | '#ffffff' | Border color |
<!-- Default border --><profile-picture ext-customer-id="demo-user-1769431807927-pd9dtmn1" alt="Kerry Nicholson" size="xl" border border-width="2" border-color="#ffffff"></profile-picture><!-- Indigo border --><profile-picture ext-customer-id="demo-user-1769429613186-q8x65t0" alt="Sarah Chen" size="xl" border border-width="4" border-color="#6366f1"></profile-picture><!-- Pink thick border --><profile-picture ext-customer-id="demo-user-1769430228786-ompo3g1" alt="Emma Liu" size="xl" border border-width="6" border-color="#ec4899"></profile-picture>Transform
| Attribute | Type | Default | Description |
|---|---|---|---|
rotation | number | 0 | Rotation angle in degrees |
zoom | number | 1.2 | Zoom level (values greater than 1 zoom in) |
<profile-picture ext-customer-id="demo-user-1769431807927-pd9dtmn1" alt="Kerry Nicholson" size="xl" rotation="15"></profile-picture><profile-picture ext-customer-id="demo-user-1769429613186-q8x65t0" alt="Sarah Chen" size="xl" rotation="-10" zoom="1.5"></profile-picture>Background
| Attribute | Type | Default | Description |
|---|---|---|---|
bg-color | string | — | Background color (any valid CSS color) |
bg-gradient | string | — | Background gradient (any valid CSS gradient) |
These are visible when the image has transparency or has not yet loaded.
<profile-picture ext-customer-id="demo-user-1769431807927-pd9dtmn1" alt="Kerry Nicholson" size="xl" image-mode="transparent" bg-color="#6366f1"></profile-picture><profile-picture ext-customer-id="demo-user-1769429613186-q8x65t0" alt="Sarah Chen" size="xl" image-mode="transparent"bg-gradient="linear-gradient(135deg, #667eea 0%, #764ba2 100%)"></profile-picture>Glow Effect
The glow attribute accepts a JSON string of a GlowConfig object.
| Property | Type | Default | Description |
|---|---|---|---|
color | string | border color | Glow color |
intensity | number | — | Intensity from 0 to 1 |
animate | boolean | false | Animate the glow with a pulsing effect |
<!-- Static glow --><profile-picture ext-customer-id="demo-user-1769431807927-pd9dtmn1" alt="Kerry Nicholson" size="xl"glow='{"color": "#6366f1", "intensity": 0.8}'></profile-picture><!-- Animated glow --><profile-picture ext-customer-id="demo-user-1769429613186-q8x65t0" alt="Sarah Chen" size="xl"glow='{"color": "#ec4899", "intensity": 0.8, "animate": true}'></profile-picture>Ring Effect
The ring attribute accepts a JSON string of a RingConfig object. Supports solid colors, gradients, animation, and progress indicators.
| Property | Type | Default | Description |
|---|---|---|---|
show | boolean | — | Show ring |
color | string | — | Ring color |
gradient | string[] | — | Gradient colors for a multi-color ring |
width | number | 3 | Ring width in pixels |
gap | number | 3 | Gap between the ring and the avatar |
animate | boolean | false | Animate the ring |
progress | number | — | Progress percentage from 0 to 100 |
emptyColor | string | — | Color for the unfilled portion of a progress ring |
<!-- Solid ring --><profile-picture ext-customer-id="demo-user-1769431807927-pd9dtmn1" alt="Kerry Nicholson" size="xl"ring='{"show": true, "color": "#6366f1", "width": 3}'></profile-picture><!-- Gradient ring with animation --><profile-picture ext-customer-id="demo-user-1769429613186-q8x65t0" alt="Sarah Chen" size="xl"ring='{"show": true, "gradient": ["#ec4899", "#8b5cf6", "#6366f1"], "animate": true}'></profile-picture><!-- Progress ring --><profile-picture ext-customer-id="demo-user-1769430228786-ompo3g1" alt="Emma Liu" size="xl"ring='{"show": true, "progress": 75, "color": "#10b981", "emptyColor": "#374151"}'></profile-picture>Presence Indicator
The presence attribute accepts a JSON string of a PresenceConfig object.
| Property | Type | Default | Description |
|---|---|---|---|
status | 'online' | 'away' | 'busy' | 'offline' | 'dnd' | — | Current status |
animate | boolean | false | Show animated ring around the indicator |
thickness | 1 | 2 | 3 | 2 | Ring thickness |
Status Colors
| Status | Color |
|---|---|
online | #30D158 |
away | #FFD60A |
busy | #FF453A |
offline | #8E8E93 |
dnd | #FF453A |
<profile-picture ext-customer-id="demo-user-1769431807927-pd9dtmn1" alt="Kerry Nicholson" size="xl"presence='{"status": "online", "animate": true}'></profile-picture><profile-picture ext-customer-id="demo-user-1769429613186-q8x65t0" alt="Sarah Chen" size="xl"presence='{"status": "away"}'></profile-picture><profile-picture ext-customer-id="demo-user-1769430228786-ompo3g1" alt="Emma Liu" size="xl"presence='{"status": "busy"}'></profile-picture><profile-picture ext-customer-id="demo-user-1769430441537-fs5i098" alt="Marcus Webb" size="xl"presence='{"status": "dnd"}'></profile-picture><profile-picture ext-customer-id="demo-user-1769431068241-t5mkiym" alt="Alice Spark" size="xl"presence='{"status": "offline"}'></profile-picture>Badge
The badge attribute accepts a JSON string of a BadgeConfig object. Useful for notification counts, verification marks, or status dots.
| Property | Type | Default | Description |
|---|---|---|---|
content | string | number | — | Text, number, or leave empty for a dot |
position | Position | 'bottom-right' | Badge position |
color | string | — | Text or icon color |
bgColor | string | — | Background color |
borderRadius | string | '9999px' | Border radius |
pulse | boolean | false | Enable pulse animation |
glow | boolean | false | Enable glow effect |
max | number | — | Maximum value (displays 99+ if exceeded) |
icon | string | — | Icon before content (emoji or Unicode character) |
Position Options
top-left | top-center | top-right | bottom-left | bottom-center | bottom-right
<!-- Notification count with pulse --><profile-picture ext-customer-id="demo-user-1769431807927-pd9dtmn1" alt="Kerry Nicholson" size="xl"badge='{"content": 5, "position": "top-right", "bgColor": "#ef4444", "pulse": true}'></profile-picture><!-- Status dot --><profile-picture ext-customer-id="demo-user-1769429613186-q8x65t0" alt="Sarah Chen" size="xl"badge='{"position": "bottom-right", "bgColor": "#10b981"}'></profile-picture><!-- With icon --><profile-picture ext-customer-id="demo-user-1769430228786-ompo3g1" alt="Emma Liu" size="xl"badge='{"icon": "✓", "content": "Verified", "bgColor": "#3b82f6"}'></profile-picture>Loading
| Attribute | Type | Default | Description |
|---|---|---|---|
loading | 'lazy' | 'eager' | 'lazy' | Image loading strategy |
placeholder | 'shimmer' | 'pulse' | 'blur' | 'skeleton' | 'none' | 'shimmer' | Placeholder animation while loading |
placeholder-color | string | '#f3f4f6' | Placeholder background color |
<profile-picture
ext-customer-id="demo-user-1769431807927-pd9dtmn1"
alt="Kerry Nicholson"
loading="eager"
placeholder="blur"
placeholder-color="#e5e7eb"
></profile-picture>Fallback
| Attribute | Type | Default | Description |
|---|---|---|---|
fallback | string | — | Custom fallback text |
fallback-mode | 'initials' | 'gradient' | — | Fallback display mode |
When no image is available, the component renders a fallback:
initialsmode generates initials from thealttext and displays them on a colored background.gradientmode shows a unique gradient derived from the name, providing a visually distinct placeholder for each user.
<!-- Initials fallback --><profile-picture alt="Jane Smith" size="xl" fallback-mode="initials"></profile-picture><!-- Gradient fallback --><profile-picture alt="Bob Wilson" size="xl" fallback-mode="gradient"></profile-picture><!-- Custom fallback text --><profile-picture alt="Jane Smith" size="xl" fallback="JS" fallback-mode="initials"></profile-picture>Interaction
The interactive attribute accepts a JSON string of an InteractionConfig object.
| Property | Type | Default | Description |
|---|---|---|---|
hoverable | boolean | false | Enable hover effects (scale and brightness change) |
pressable | boolean | false | Enable press/click effects |
focusable | boolean | false | Show a focus ring for keyboard navigation |
cursor | 'pointer' | 'default' | 'zoom-in' | — | Cursor style on hover |
<profile-picture ext-customer-id="demo-user-1769431807927-pd9dtmn1" alt="Kerry Nicholson" size="xl"interactive='{"hoverable": true, "pressable": true, "cursor": "pointer"}'></profile-picture>Static Methods
| Method | Signature | Description |
|---|---|---|
setCdnBaseUrl | (url: string) => void | Set the global CDN base URL for all instances |
getCdnBaseUrl | () => string | Get the current CDN base URL |
<script type="module">
import '@grasco/profile-picture/standalone';
// The default CDN base URL is https://api.propicture.app
// Override if needed:
customElements.whenDefined('profile-picture').then(() => {
const PP = customElements.get('profile-picture');
PP.setCdnBaseUrl('https://cdn.example.com');
});
</script>Examples
Messaging List Avatar
Restrained presence dot and soft hover. Optimized for dense chat lists where the avatar is a visual anchor, not a distraction.
<profile-pictureext-customer-id="demo-user-1769431807927-pd9dtmn1"alt="Kerry Nicholson"size="md"shadow="none"presence='{"status": "online", "thickness": 2}'interactive='{"hoverable": true, "cursor": "pointer"}'></profile-picture>Story Ring
A refined take on the story-ring pattern — warm gradient, generous gap, thin stroke.
<profile-pictureext-customer-id="demo-user-1769429613186-q8x65t0"alt="Sarah Chen"size="xl"shadow="none"ring='{"show": true, "gradient": ["#f59e0b", "#ef4444", "#ec4899"], "width": 2, "gap": 4}'></profile-picture>Verified Creator
Squircle silhouette with a small verification mark. Clean enough for a profile header.
<profile-pictureext-customer-id="demo-user-1769430228786-ompo3g1"alt="Emma Liu"size="2xl"variant="squircle"shadow="md"badge='{"icon": "✓", "bgColor": "#0ea5e9", "color": "#ffffff", "position": "bottom-right"}'></profile-picture>Onboarding Progress
A progress ring around the avatar — great for profile completion, course progress, or goal tracking.
<profile-pictureext-customer-id="demo-user-1769430441537-fs5i098"alt="Marcus Webb"size="xl"shadow="none"ring='{"show": true, "progress": 68, "color": "#10b981", "emptyColor": "#e5e7eb", "width": 3, "gap": 3}'></profile-picture>Focus Mode
A subtle do-not-disturb signal — dimmed presence with a calm indicator, no shouting.
<profile-pictureext-customer-id="demo-user-1769431068241-t5mkiym"alt="Alice Spark"size="lg"shadow="sm"presence='{"status": "dnd", "thickness": 2}'badge='{"icon": "🌙", "bgColor": "#1f2937", "color": "#ffffff", "position": "top-right"}'></profile-picture>