Responsive image with lazy loading, placeholders, and error fallback
Tags: component media display
Image wraps the native <img> element with the behaviour most pages end up hand-rolling: lazy loading, a placeholder while the file downloads, and a graceful fallback when it never arrives.
alt is required at the type level. Pass an empty string for decorative images so the intent is explicit rather than forgotten.
Import
<script>
import { Image } from '@classic-homes/theme-svelte';
</script>Basic Usage
<Image src="/photo.jpg" alt="Sunrise over the harbour" ratio="photo" />Props
| Prop | Type | Default | Description |
|---|---|---|---|
src |
string |
required | Image URL |
alt |
string |
required | Alternative text; required, empty string for decorative images |
ratio |
'square' | 'video' | 'photo' | 'portrait' | 'wide' | number |
- | Constrain the image to a ratio box |
fit |
'cover' | 'contain' | 'fill' | 'none' | 'scale-down' |
'cover' |
How the image fills its box |
rounded |
'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full' |
'none' |
Corner rounding |
placeholder |
string |
- | Low-resolution data URL blurred in while loading |
showSkeleton |
boolean |
true |
Show a skeleton while loading (ignored when placeholder is set) |
loading |
'lazy' | 'eager' |
'lazy' |
Native loading strategy |
decoding |
'async' | 'sync' | 'auto' |
'async' |
Native decoding hint |
srcset |
string |
- | Responsive candidate list |
sizes |
string |
- | Sizes attribute paired with srcset |
onload |
(event: Event) => void |
- | Called once the image loads |
onerror |
(event: Event) => void |
- | Called when the image fails to load |
class |
string |
- | Additional classes for the wrapper |
imgClass |
string |
- | Additional classes for the <img> element |
fallback |
Snippet |
- | Custom content rendered in place of a failed image |
overlay |
Snippet |
- | Content overlaid on the image, such as a caption or badge |
Snippets
| Snippet | Description |
|---|---|
fallback |
Custom content shown when the image fails |
overlay |
Content layered over the image |
Loading Placeholders
A placeholder is rendered blurred behind the real image and cross-faded out on load. Without one, a skeleton fills the box instead:
<Image
src="/hero-full.jpg"
alt="Hero image"
placeholder="data:image/jpeg;base64,/9j/4AAQ..."
ratio="wide"
/>Above-the-Fold Images
Lazy loading is the wrong default for anything visible on first paint. Opt out for hero images:
<Image src="/hero.jpg" alt="Hero" loading="eager" fetchpriority="high" ratio="wide" />Error Fallback
<Image src={avatarUrl} alt={userName} ratio="square" rounded="full">
{#snippet fallback()}
<span class="text-sm font-medium">{userName.charAt(0)}</span>
{/snippet}
</Image>Accessibility
altis required by the type signature, so an unlabelled image cannot compile.- Decorative images take
alt="", which removes them from the accessibility tree. - The blurred placeholder is marked
aria-hidden, so it is never announced as a second image. - The error state carries the alt text, so a failure is still described rather than silent.
Related Components
- AspectRatio - The ratio box Image uses internally
- MediaGrid - Renders many images as a gallery
- Lightbox - Full-screen viewer with zoom
- Avatar - Purpose-built for profile images
- Skeleton - The loading placeholder Image falls back to