Gallery lab — PDP image selector preview





MirabelleSweetheart tulle midi dress | Butter yellow
Colour — Butter yellow
Size
Wander Doll's PDP gallery, ported to Hazeldoe
The gallery above is live and responsive. Widen past 1101px and it becomes a two-column grid that scrolls independently of the buy column. Narrow under 640px, or open this page on your phone, and the same element becomes a full-bleed snap carousel with a hairline progress bar. Nothing is duplicated — one element changes layout mode.
- Desktop — display:grid, two equal columns, gap:2px, each cell calc(100svh − header). Gallery and buy column are separate scroll containers with scrollbars hidden. The buy column is not sticky — it is its own scroller.
- Mobile — display:flex row, overflow-x:auto, scroll-snap-type:x mandatory, cells at full gallery width. The 2px hairline is the only navigation: no dots, no arrows, no counter.
- Every image uses object-fit:cover with object-position:center top, which keeps the face in frame on a tall crop.
- Colourway swatches are 96px wide at aspect-ratio:2/3 with border-radius:8px, in a horizontal scroll strip. Active state is a 1px ink border.
| Property | Wander Doll | Hazeldoe now |
|---|---|---|
| Desktop layout | grid, 2 cols, gap:2px | Single-column media stack |
| Desktop cell height | calc(100vh − 105px) | Intrinsic, from image aspect |
| Gallery scroll | Own container, scrollbar hidden | Page scroll |
| Buy column | overflow-y:auto, static | position:sticky |
| Mobile cell size | 100vw × calc(100svh − 232px) | Full-width aspect-ratio box |
| Mobile affordance | 2px progress hairline | Dots |
| Image fit | cover + center top | cover, centred |
| Colour swatch | 96px, 2/3, radius:8px | Square swatches, wrapped row |
| Breakpoint | 1100 / 1101px | 999px |
This is a preview page, not the product template. Your real PDP is untouched. Images are the Mirabelle butter-yellow shots; the swatches, sizes and button are dressing so the gallery can be judged in context.
Two Prestige-specific snags. Prestige puts 24px top and bottom margin on every .product-info__block-item, and .product is a grid with gap:30px — both fight a full-bleed gallery. And the header height in calc() has to be driven from a variable, or the gallery drifts out of sync whenever the header changes.
The source images are 4:5, not 2:3. The crop here is tighter than it would be with 2:3 files. Worth knowing before judging the framing.

