A card with an image on top and a title, subtitle and meta row below, for artwork lists, artist tiles and booking previews. It composes `atoms.card` with no padding, so fill, border and corners are Card's.

pnpm add @behivetech/molecules.image-card

You are viewing Image Card v0.2.0, snapshotted 2026-11-09. The latest is v0.2.2. Go to the latest →

Examples of v0.2.0 are shown as code; only the latest version runs live. Open the live examples →

A linked artwork card: the whole card is one link named by the title.

Linked Image Card
1const PLACEHOLDER_IMAGE =
2 "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='500'><rect width='400' height='500' fill='%23bc13fe'/></svg>";
3
4const LinkedImageCard = () => (
5 <ImageCard
6 href="/art/blue-hour"
7 media={
8 <img
9 src={PLACEHOLDER_IMAGE}
10 alt="Blue hour on the porch, oil on canvas"
11 />
12 }
13 title="Blue hour on the porch"
14 subtitle="Lena Park"
15 meta="$480.00"
16 />
17);
18
19render(<LinkedImageCard />);

A static card with a square media box, as for an artist tile.

Square Image Card
1const PLACEHOLDER_IMAGE =
2 "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='500'><rect width='400' height='500' fill='%23bc13fe'/></svg>";
3
4const SquareImageCard = () => (
5 <ImageCard
6 aspectRatio="1/1"
7 media={<img src={PLACEHOLDER_IMAGE} alt="Lena Park in her studio" />}
8 title="Lena Park"
9 />
10);
11
12render(<SquareImageCard />);

A 3/2 media box, as for a booking preview.

Wide Image Card
1const PLACEHOLDER_IMAGE =
2 "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='500'><rect width='400' height='500' fill='%23bc13fe'/></svg>";
3
4const WideImageCard = () => (
5 <ImageCard
6 aspectRatio="3/2"
7 href="/bookings/studio-visit"
8 media={<img src={PLACEHOLDER_IMAGE} alt="The studio, morning light" />}
9 title="Studio visit"
10 subtitle="Saturday, 10:00"
11 />
12);
13
14render(<WideImageCard />);

An image that fails to load shows the image icon at the same ratio.

Failed Image Card
1const BROKEN_IMAGE = "https://invalid.example/missing.jpg";
2
3const FailedImageCard = () => (
4 <ImageCard
5 media={
6 <img src={BROKEN_IMAGE} alt="Hive study no. 3, the garden at dusk" />
7 }
8 title="Hive study no. 3, the garden at dusk"
9 subtitle="Theo Grant"
10 meta="$1,250.00"
11 />
12);
13
14render(<FailedImageCard />);

Cards in a responsive grid row: two across from a 352px container, more as it widens, with a long title and a missing subtitle.

Image Card Grid Row
1const PLACEHOLDER_IMAGE =
2 "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='500'><rect width='400' height='500' fill='%23bc13fe'/></svg>";
3
4const ImageCardGridRow = () => (
5 <div
6 style={{
7 display: "grid",
8 gridTemplateColumns: "repeat(auto-fill, minmax(10.5rem, 1fr))",
9 gap: "1rem",
10 }}
11 >
12 <ImageCard
13 href="/art/blue-hour"
14 media={<img src={PLACEHOLDER_IMAGE} alt="Blue hour on the porch" />}
15 title="Blue hour on the porch"
16 subtitle="Lena Park"
17 meta="$480.00"
18 />
19 <ImageCard
20 href="/art/hive-study-3"
21 media={<img src={PLACEHOLDER_IMAGE} alt="Hive study no. 3" />}
22 title="Hive study no. 3, the garden at dusk, with a title long enough to clamp"
23 subtitle="Theo Grant"
24 meta="$1,250.00"
25 />
26 <ImageCard
27 href="/art/morning-wall"
28 media={<img src={PLACEHOLDER_IMAGE} alt="Morning wall" />}
29 title="Morning wall"
30 />
31 </div>
32);
33
34render(<ImageCardGridRow />);