Components Media & code
Image
StableAn image with lazy loading, a reserved ratio and a graceful fallback.
Image wraps <img> with lazy loading, asynchronous decoding, rounded corners from tokens and an optional ratio that stops layout shift. When the source fails to load it shows a neutral placeholder that keeps the alt text available to assistive technology.
Overview
import { Image } from '@bindshq/stance-react';
const svg = encodeURIComponent(
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180"><rect width="320" height="180" fill="#ECE6DF"/><rect x="24" y="24" width="120" height="14" rx="7" fill="#140C2E"/><rect x="24" y="48" width="200" height="8" rx="4" fill="#817D8C"/><rect x="24" y="64" width="160" height="8" rx="4" fill="#9E9AA3"/><circle cx="270" cy="130" r="34" fill="#140C2E"/></svg>`,
);
const preview = `data:image/svg+xml,${svg}`;
export function Basic() {
return (
<Image
src={preview}
alt="Email signature preview for Acme Ltd"
ratio={16 / 9}
radius="lg"
bordered
style={{ width: 320 }}
/>
);
}Light, dark and high contrast
Every Stance component is designed and tested in all three appearance modes.
Import
import { Image } from '@bindshq/stance-react';Examples
Fallback
A broken source shows a placeholder.

import { Image } from '@bindshq/stance-react';
const svg = encodeURIComponent(
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180"><rect width="320" height="180" fill="#ECE6DF"/><rect x="24" y="24" width="120" height="14" rx="7" fill="#140C2E"/><rect x="24" y="48" width="200" height="8" rx="4" fill="#817D8C"/><rect x="24" y="64" width="160" height="8" rx="4" fill="#9E9AA3"/><circle cx="270" cy="130" r="34" fill="#140C2E"/></svg>`,
);
const preview = `data:image/svg+xml,${svg}`;
export function Fallback() {
return (
<Image
src="/missing-signature.png"
alt="Signature preview unavailable"
ratio={16 / 9}
style={{ width: 320 }}
/>
);
}import { Image } from '@bindshq/stance-react';
const svg = encodeURIComponent(
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180"><rect width="320" height="180" fill="#ECE6DF"/><rect x="24" y="24" width="120" height="14" rx="7" fill="#140C2E"/><rect x="24" y="48" width="200" height="8" rx="4" fill="#817D8C"/><rect x="24" y="64" width="160" height="8" rx="4" fill="#9E9AA3"/><circle cx="270" cy="130" r="34" fill="#140C2E"/></svg>`,
);
const preview = `data:image/svg+xml,${svg}`;
export function Shapes() {
return (
<div style={{ display: 'flex', gap: 16, alignItems: 'center' }}>
<Image src={preview} alt="Square crop" ratio={1} radius="none" style={{ width: 96 }} />
<Image src={preview} alt="Rounded crop" ratio={1} radius="xl" style={{ width: 96 }} />
<Image src={preview} alt="Circular crop" ratio={1} radius="full" style={{ width: 96 }} />
</div>
);
}API reference
| Prop | Type | Default | Description |
|---|---|---|---|
alt* required | string | None | Text alternative; empty for decorative images. |
ratio | number | None | Width ÷ height to reserve space. |
fit | 'cover' | 'contain' | 'fill' | 'none' | 'cover' | object-fit. |
radius | 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'md' | Corner radius. |
bordered | boolean | None | Subtle border for screenshots. |
fallback | ReactNode | None | Content when loading fails. |
Accessibility
- alt is required by the type. Pass alt="" for decorative images.
- Fallbacks keep the alt text via role="img".
Usage guidelines
Do
- Describe what the image conveys, not what it looks like.
Don’t
- Embed text in images.