Skip to content

Contact Sheet

A framed image gallery with numbered photographic thumbnails.

LIVE PREVIEWInteract with the component
Just React. No extra dependencies.

Copy the component and its CSS module into your project.

CSS Modules

Usage

Matches your current playground settings.

jsx
import ContactSheet from "./ContactSheet";
export default function Example() {
return (
<ContactSheet
items={[
{
"id": "fold",
"src": "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22800%22%20height%3D%221000%22%20viewBox%3D%220%200%20800%201000%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22bg%22%20x2%3D%221%22%20y2%3D%221%22%3E%3Cstop%20stop-color%3D%22%23e3d8c5%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23a6a09d%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22blue%22%20x2%3D%221%22%20y2%3D%221%22%3E%3Cstop%20stop-color%3D%22%23bdd0dc%22%2F%3E%3Cstop%20offset%3D%22.45%22%20stop-color%3D%22%236e879f%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23283a50%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22cream%22%20x2%3D%221%22%20y2%3D%22.8%22%3E%3Cstop%20stop-color%3D%22%23f8e9d0%22%2F%3E%3Cstop%20offset%3D%22.5%22%20stop-color%3D%22%23d4b38e%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23896854%22%2F%3E%3C%2FlinearGradient%3E%3CradialGradient%20id%3D%22shade%22%3E%3Cstop%20stop-color%3D%22%23272026%22%20stop-opacity%3D%22.4%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23272026%22%20stop-opacity%3D%220%22%2F%3E%3C%2FradialGradient%3E%3C%2Fdefs%3E%3Cpath%20fill%3D%22url(%23bg)%22%20d%3D%22M0%200h800v1000H0z%22%2F%3E%3Cellipse%20cx%3D%22423%22%20cy%3D%22792%22%20rx%3D%22280%22%20ry%3D%2285%22%20fill%3D%22url(%23shade)%22%2F%3E%3Cpath%20fill%3D%22url(%23blue)%22%20d%3D%22m230%20290%20190-70%20180%20150-50%20350-160%2095-170-190Z%22%2F%3E%3Cpath%20fill%3D%22%23bdc9d0%22%20d%3D%22m230%20290%20190-70-30%20340-170%2065Z%22%2F%3E%3Cpath%20fill%3D%22%23718ca1%22%20d%3D%22m420%20220%20180%20150-175%20170-35%2020Z%22%2F%3E%3Cpath%20fill%3D%22%23344b61%22%20d%3D%22m425%20540%20175-170-50%20350-160%2095Z%22%2F%3E%3Cpath%20fill%3D%22%239bafbd%22%20d%3D%22m220%20625%20170-65v255Z%22%2F%3E%3C%2Fsvg%3E",
"alt": "Folded blue sculpture on warm stone",
"caption": "Fold study"
},
{
"id": "ribs",
"src": "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22800%22%20height%3D%221000%22%20viewBox%3D%220%200%20800%201000%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22bg%22%20x2%3D%221%22%20y2%3D%221%22%3E%3Cstop%20stop-color%3D%22%23e3d8c5%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23a6a09d%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22blue%22%20x2%3D%221%22%20y2%3D%221%22%3E%3Cstop%20stop-color%3D%22%23bdd0dc%22%2F%3E%3Cstop%20offset%3D%22.45%22%20stop-color%3D%22%236e879f%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23283a50%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22cream%22%20x2%3D%221%22%20y2%3D%22.8%22%3E%3Cstop%20stop-color%3D%22%23f8e9d0%22%2F%3E%3Cstop%20offset%3D%22.5%22%20stop-color%3D%22%23d4b38e%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23896854%22%2F%3E%3C%2FlinearGradient%3E%3CradialGradient%20id%3D%22shade%22%3E%3Cstop%20stop-color%3D%22%23272026%22%20stop-opacity%3D%22.4%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23272026%22%20stop-opacity%3D%220%22%2F%3E%3C%2FradialGradient%3E%3C%2Fdefs%3E%3Cpath%20fill%3D%22%23221b19%22%20d%3D%22M0%200h800v1000H0z%22%2F%3E%3Cellipse%20cx%3D%22400%22%20cy%3D%22820%22%20rx%3D%22260%22%20ry%3D%2265%22%20fill%3D%22url(%23shade)%22%2F%3E%3Crect%20x%3D%22170%22%20y%3D%22285%22%20width%3D%2230%22%20height%3D%22530%22%20rx%3D%2215%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22187%22%20y%3D%22279.78%22%20width%3D%2235.57%22%20height%3D%22530%22%20rx%3D%2217.785%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22204%22%20y%3D%22274.62%22%20width%3D%2241.07%22%20height%3D%22530%22%20rx%3D%2220.535%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22221%22%20y%3D%22269.61%22%20width%3D%2246.42%22%20height%3D%22530%22%20rx%3D%2223.21%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22238%22%20y%3D%22264.8%22%20width%3D%2251.54%22%20height%3D%22530%22%20rx%3D%2225.77%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22255%22%20y%3D%22260.27%22%20width%3D%2256.38%22%20height%3D%22530%22%20rx%3D%2228.19%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22272%22%20y%3D%22256.07%22%20width%3D%2260.85%22%20height%3D%22530%22%20rx%3D%2230.425%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22289%22%20y%3D%22252.27%22%20width%3D%2264.91%22%20height%3D%22530%22%20rx%3D%2232.455%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22306%22%20y%3D%22248.9%22%20width%3D%2268.5%22%20height%3D%22530%22%20rx%3D%2234.25%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22323%22%20y%3D%22246.03%22%20width%3D%2271.57%22%20height%3D%22530%22%20rx%3D%2235.785%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22340%22%20y%3D%22243.68%22%20width%3D%2274.07%22%20height%3D%22530%22%20rx%3D%2237.035%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22357%22%20y%3D%22241.89%22%20width%3D%2275.98%22%20height%3D%22530%22%20rx%3D%2237.99%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22374%22%20y%3D%22240.68%22%20width%3D%2277.27%22%20height%3D%22530%22%20rx%3D%2238.635%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22391%22%20y%3D%22240.08%22%20width%3D%2277.92%22%20height%3D%22530%22%20rx%3D%2238.96%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22408%22%20y%3D%22240.08%22%20width%3D%2277.92%22%20height%3D%22530%22%20rx%3D%2238.96%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22425%22%20y%3D%22240.68%22%20width%3D%2277.27%22%20height%3D%22530%22%20rx%3D%2238.635%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22442%22%20y%3D%22241.89%22%20width%3D%2275.98%22%20height%3D%22530%22%20rx%3D%2237.99%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22459%22%20y%3D%22243.68%22%20width%3D%2274.07%22%20height%3D%22530%22%20rx%3D%2237.035%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22476%22%20y%3D%22246.03%22%20width%3D%2271.57%22%20height%3D%22530%22%20rx%3D%2235.785%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22493%22%20y%3D%22248.9%22%20width%3D%2268.5%22%20height%3D%22530%22%20rx%3D%2234.25%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22510%22%20y%3D%22252.27%22%20width%3D%2264.91%22%20height%3D%22530%22%20rx%3D%2232.455%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22527%22%20y%3D%22256.07%22%20width%3D%2260.85%22%20height%3D%22530%22%20rx%3D%2230.425%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22544%22%20y%3D%22260.27%22%20width%3D%2256.38%22%20height%3D%22530%22%20rx%3D%2228.19%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22561%22%20y%3D%22264.8%22%20width%3D%2251.54%22%20height%3D%22530%22%20rx%3D%2225.77%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22578%22%20y%3D%22269.61%22%20width%3D%2246.42%22%20height%3D%22530%22%20rx%3D%2223.21%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22595%22%20y%3D%22274.62%22%20width%3D%2241.07%22%20height%3D%22530%22%20rx%3D%2220.535%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22612%22%20y%3D%22279.78%22%20width%3D%2235.57%22%20height%3D%22530%22%20rx%3D%2217.785%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22629%22%20y%3D%22285%22%20width%3D%2230%22%20height%3D%22530%22%20rx%3D%2215%22%20fill%3D%22url(%23cream)%22%2F%3E%3C%2Fsvg%3E",
"alt": "A ribbed ceramic form in soft amber light",
"caption": "Rhythm in clay"
},
{
"id": "portal",
"src": "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22800%22%20height%3D%221000%22%20viewBox%3D%220%200%20800%201000%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22bg%22%20x2%3D%221%22%20y2%3D%221%22%3E%3Cstop%20stop-color%3D%22%23e3d8c5%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23a6a09d%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22blue%22%20x2%3D%221%22%20y2%3D%221%22%3E%3Cstop%20stop-color%3D%22%23bdd0dc%22%2F%3E%3Cstop%20offset%3D%22.45%22%20stop-color%3D%22%236e879f%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23283a50%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22cream%22%20x2%3D%221%22%20y2%3D%22.8%22%3E%3Cstop%20stop-color%3D%22%23f8e9d0%22%2F%3E%3Cstop%20offset%3D%22.5%22%20stop-color%3D%22%23d4b38e%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23896854%22%2F%3E%3C%2FlinearGradient%3E%3CradialGradient%20id%3D%22shade%22%3E%3Cstop%20stop-color%3D%22%23272026%22%20stop-opacity%3D%22.4%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23272026%22%20stop-opacity%3D%220%22%2F%3E%3C%2FradialGradient%3E%3C%2Fdefs%3E%3Cpath%20fill%3D%22%23c8bfb0%22%20d%3D%22M0%200h800v1000H0z%22%2F%3E%3Ccircle%20cx%3D%22515%22%20cy%3D%22260%22%20r%3D%22100%22%20fill%3D%22%23eee2be%22%2F%3E%3Cpath%20d%3D%22M0%20640h200V520h200V400h200V280h200v720H0Z%22%20fill%3D%22%23a26450%22%2F%3E%3Cpath%20d%3D%22M0%20740h200V620h200V500h200V380h200v620H0Z%22%20fill%3D%22%23c58d72%22%2F%3E%3Cpath%20d%3D%22M0%20850h200V730h200V610h200V490h200v510H0Z%22%20fill%3D%22%23dfb397%22%2F%3E%3C%2Fsvg%3E",
"alt": "A circular pale sun above terracotta architectural steps",
"caption": "Quiet geometry"
},
{
"id": "balance",
"src": "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22800%22%20height%3D%221000%22%20viewBox%3D%220%200%20800%201000%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22bg%22%20x2%3D%221%22%20y2%3D%221%22%3E%3Cstop%20stop-color%3D%22%23e3d8c5%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23a6a09d%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22blue%22%20x2%3D%221%22%20y2%3D%221%22%3E%3Cstop%20stop-color%3D%22%23bdd0dc%22%2F%3E%3Cstop%20offset%3D%22.45%22%20stop-color%3D%22%236e879f%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23283a50%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22cream%22%20x2%3D%221%22%20y2%3D%22.8%22%3E%3Cstop%20stop-color%3D%22%23f8e9d0%22%2F%3E%3Cstop%20offset%3D%22.5%22%20stop-color%3D%22%23d4b38e%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23896854%22%2F%3E%3C%2FlinearGradient%3E%3CradialGradient%20id%3D%22shade%22%3E%3Cstop%20stop-color%3D%22%23272026%22%20stop-opacity%3D%22.4%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23272026%22%20stop-opacity%3D%220%22%2F%3E%3C%2FradialGradient%3E%3C%2Fdefs%3E%3Cpath%20fill%3D%22%237c909c%22%20d%3D%22M0%200h800v1000H0z%22%2F%3E%3Cellipse%20cx%3D%22420%22%20cy%3D%22820%22%20rx%3D%22260%22%20ry%3D%2280%22%20fill%3D%22url(%23shade)%22%2F%3E%3Crect%20x%3D%22235%22%20y%3D%22510%22%20width%3D%22330%22%20height%3D%22290%22%20rx%3D%22145%22%20fill%3D%22url(%23cream)%22%2F%3E%3Crect%20x%3D%22185%22%20y%3D%22260%22%20width%3D%22440%22%20height%3D%22250%22%20rx%3D%22125%22%20transform%3D%22rotate(-18%20405%20385)%22%20fill%3D%22url(%23blue)%22%2F%3E%3C%2Fsvg%3E",
"alt": "Two rounded stone forms balanced in a blue studio",
"caption": "Weight & balance"
}
]}
defaultIndex={0}
accentColor={"#d5a76c"}
aspectRatio={"4 / 3"}
label={"Sculpture studies"}
/>
);
}

Using Contact Sheet

Provide image URLs and meaningful alt text through items. Use caption for a short visible image description, and aspectRatio to reserve the main frame.

Pass activeIndex and onIndexChange to synchronise selection with your own state. Thumbnail buttons support keyboard activation and remain scrollable in narrow containers.

Props

NameTypeRequiredDefaultDescription
itemsArray<{ id?, src, alt?, label?, caption? }>No[]Images, accessible descriptions and optional captions.
activeIndexnumberNoundefinedControlled selected image index.
defaultIndexnumberNo0Initial index in uncontrolled mode.
onIndexChangefunctionNoundefinedReceives the selected index.
accentColorstringNo"#d5a76c"Thumbnail selection and focus colour.
aspectRatiostringNo"4 / 3"CSS aspect ratio of the main image.
labelstringNo"Image gallery"Accessible gallery label.
classNamestringNo""Additional classes on the root element.
styleCSSPropertiesNoundefinedInline styles for sizing, typography and appearance.

Related components

Transparent image layers separate in depth as the pointer crosses the scene.

An image separates into polished vertical slivers that shift with the pointer.

An editorial image grid opens into a focused, keyboard-accessible viewing room.