Grasco
Profile Picture UI

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

AttributeTypeDefaultDescription
srcstringImage source URL
altstring''Alt text for accessibility
ext-customer-idstringExternal 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

AttributeTypeDefaultDescription
sizeSize | number'md'Predefined size or custom pixel value

Size Map

TokenPixels
2xs20px
xs24px
sm32px
md40px
lg48px
xl64px
2xl80px
3xl120px
<!-- 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

AttributeTypeDefaultDescription
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

AttributeTypeDefaultDescription
borderbooleanfalseEnable border
border-width1 | 2 | 3 | 4 | 5 | 6 | 82Border width in pixels
border-colorstring'#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

AttributeTypeDefaultDescription
rotationnumber0Rotation angle in degrees
zoomnumber1.2Zoom 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

AttributeTypeDefaultDescription
bg-colorstringBackground color (any valid CSS color)
bg-gradientstringBackground 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.

PropertyTypeDefaultDescription
colorstringborder colorGlow color
intensitynumberIntensity from 0 to 1
animatebooleanfalseAnimate 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.

PropertyTypeDefaultDescription
showbooleanShow ring
colorstringRing color
gradientstring[]Gradient colors for a multi-color ring
widthnumber3Ring width in pixels
gapnumber3Gap between the ring and the avatar
animatebooleanfalseAnimate the ring
progressnumberProgress percentage from 0 to 100
emptyColorstringColor 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.

PropertyTypeDefaultDescription
status'online' | 'away' | 'busy' | 'offline' | 'dnd'Current status
animatebooleanfalseShow animated ring around the indicator
thickness1 | 2 | 32Ring thickness

Status Colors

StatusColor
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.

PropertyTypeDefaultDescription
contentstring | numberText, number, or leave empty for a dot
positionPosition'bottom-right'Badge position
colorstringText or icon color
bgColorstringBackground color
borderRadiusstring'9999px'Border radius
pulsebooleanfalseEnable pulse animation
glowbooleanfalseEnable glow effect
maxnumberMaximum value (displays 99+ if exceeded)
iconstringIcon 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

AttributeTypeDefaultDescription
loading'lazy' | 'eager''lazy'Image loading strategy
placeholder'shimmer' | 'pulse' | 'blur' | 'skeleton' | 'none''shimmer'Placeholder animation while loading
placeholder-colorstring'#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

AttributeTypeDefaultDescription
fallbackstringCustom fallback text
fallback-mode'initials' | 'gradient'Fallback display mode

When no image is available, the component renders a fallback:

  • initials mode generates initials from the alt text and displays them on a colored background.
  • gradient mode 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.

PropertyTypeDefaultDescription
hoverablebooleanfalseEnable hover effects (scale and brightness change)
pressablebooleanfalseEnable press/click effects
focusablebooleanfalseShow 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

MethodSignatureDescription
setCdnBaseUrl(url: string) => voidSet the global CDN base URL for all instances
getCdnBaseUrl() => stringGet 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>

On this page