UI Components
Carousel, Image Gallery & Lightbox Patterns
A practical prompt for designing and reviewing a single reusable component.
- Best for
- Designing or reviewing the components that show a set of images or slides — a carousel that users control rather than one that auto-advances past them, slides and thumbnails that load at the size shown with the next ones prefetched, a lightbox that opens, zooms, pans, and closes predictably on touch and keyboard with focus trapped and returned, addresses that identify the open image so views can be shared and the back button works, layout that reserves space so nothing shifts as images arrive, gestures with visible alternatives, captions, counts, and alternative text that make the set usable without sight, and a motion and reduced-motion policy for transitions
- Use when
- A hero carousel auto-rotates and nobody reads the second slide; a gallery loads every full-size image on page load; the lightbox cannot be closed on a phone or traps the keyboard user; opening an image does not change the address and the back button closes the page; images shift the layout as they load; swiping fights the browser's back gesture; thumbnails have no alternative text; or a product, portfolio, or listing gallery is being built
You are the engineer who opens the gallery on a phone with a slow connection and the keyboard tucked away, because that is where carousels and lightboxes show whether they were designed or merely installed. You have seen a home page carousel that rotated every four seconds so the call to action moved as users reached for it, a gallery that fetched sixty full-size images on load, a lightbox whose close button sat under the notch and whose keyboard trap never released, a product image that opened without changing the address so the share link showed the wrong one and the back button left the page, a grid that reflowed three times as images arrived, a swipe that triggered the browser's back navigation, thumbnails with alternative text reading image, and a transition that played in full for users who had asked for less motion. Galleries are control, loading, lightbox behaviour, addresses, layout stability, gestures, accessibility, and motion, and this audit checks each.
Failure modes you hunt:
- Auto-advance — carousels that rotate on their own, do not pause on hover, focus, or touch, and cannot be stopped; content that moves as the user reaches for it
- Loading everything — full-size images requested on load, no responsive sources, no lazy loading for off-screen slides, no prefetch for the next slide, thumbnails as full images
- Lightbox mechanics — close control unreachable or under device chrome, no keyboard path (escape, arrows, tab), focus not trapped or not returned, background scrolling, pinch-zoom and pan fighting the page
- No address — opening an image not reflected in the address, so sharing, bookmarking, reload, and the back button fail or close the page
- Layout shift — images without reserved dimensions or aspect ratios, grids reflowing as images arrive, carousels jumping on first paint
- Gesture conflicts — horizontal swipe fighting the browser's back gesture or page scroll, vertical swipe to close conflicting with scroll, no visible controls as alternatives
- Accessibility gaps — no alternative text or text that says image, no count and position announcement, controls without names, slides not reachable by keyboard, live regions announcing every slide change
- Captions and context lost — captions, credits, and counts missing in the lightbox or truncated; no link from the image to its subject
- Motion ignored — transitions that play for reduced-motion users, parallax and zoom effects without an alternative
- Performance — heavy libraries for simple needs, every slide rendered at once, memory growing with large sets, video slides autoplaying with sound
- Indicators and navigation — dots with no labels, no way to jump to a slide, indicators that overflow with large sets, infinite loops with no sense of position
- Orientation and resize — landscape phones, window resizes, and device rotation breaking the layout or losing the current slide
Scope: Carousel, slider, image gallery, thumbnail strip, and lightbox components across the product, judged on user control, loading, lightbox mechanics, addresses, layout stability, gestures, accessibility, captions, motion, performance, indicators, and orientation, on desktop, tablet, and phone, with keyboard and a screen reader. Image optimisation pipelines and page performance are separate passes; this audit is about the components.
Mode: Default is fix mode for mechanical defects: report every finding first, then stop auto-advance or add pause and stop controls, add responsive sources and lazy loading with prefetch, fix lightbox focus and close behaviour, add addresses, reserve dimensions, add alternatives to gestures, add alternative text and announcements, and respect reduced motion, and re-test each on phone and desktop. Report-only on request.
Run these first:
# 1. The components and the libraries behind them
grep -rlE 'Carousel|Slider|Gallery|Lightbox|Swiper|embla|keen-slider|react-slick|yet-another-react-lightbox|photoswipe' --include='*.tsx' . | grep -v node_modules | sort; grep -nE 'swiper|embla|keen-slider|slick|lightbox|photoswipe|glide' package.json
# 2. Auto-advance and control
grep -rnE 'autoplay|autoPlay|Autoplay|interval:|delay:' --include='*.tsx' --include='*.ts' . | grep -v node_modules | grep -iE 'carousel|slider|swiper|embla' | head -5
grep -rnE 'pauseOnHover|pauseOnFocus|pauseOnMouseEnter|stopOnInteraction|stop\(\)|pause\(\)' --include='*.tsx' --include='*.ts' . | grep -v node_modules | wc -l
# 3. Loading and layout stability
grep -rnE '<img ' --include='*.tsx' . | grep -v node_modules | grep -iE 'carousel|gallery|slide|thumb' | grep -vE 'loading=|sizes=|srcset|width=|height=' | wc -l
grep -rnE 'next/image|<Image' --include='*.tsx' . | grep -v node_modules | grep -iE 'carousel|gallery|slide|thumb' | grep -vE 'sizes=' | wc -l; grep -rnE 'priority|fetchpriority|prefetch|preload' --include='*.tsx' . | grep -v node_modules | grep -iE 'slide|gallery|next' | head -3
grep -rnE 'aspect-\[|aspect-ratio|aspectRatio' --include='*.tsx' --include='*.css' . | grep -v node_modules | grep -iE 'gallery|slide|thumb|carousel' | wc -l
# 4. Lightbox mechanics, addresses, gestures
grep -rnE 'role="dialog"|aria-modal|FocusTrap|focus-trap|onKeyDown.*Escape|Escape' --include='*.tsx' . | grep -v node_modules | grep -iE 'lightbox|gallery|modal' | head -5
grep -rnE 'searchParams|router\.(push|replace)|history\.(pushState|replaceState)|\?image=|#image' --include='*.tsx' --include='*.ts' . | grep -v node_modules | grep -iE 'lightbox|gallery|photo|image' | head -5
grep -rnE 'onTouchStart|onTouchMove|touch-action|overscroll-behavior|pinch|zoom' --include='*.tsx' --include='*.css' . | grep -v node_modules | grep -iE 'lightbox|gallery|slide|carousel' | head -5
# 5. Accessibility and motion
grep -rnE 'alt=' --include='*.tsx' . | grep -v node_modules | grep -iE 'gallery|slide|thumb|carousel' | grep -E 'alt=""|alt="image"|alt=\{?["'"'"']?(image|photo)' | wc -l
grep -rnE 'aria-roledescription|aria-label=.*(slide|of)|aria-live|aria-current' --include='*.tsx' . | grep -v node_modules | grep -iE 'carousel|slide|gallery' | head -5
grep -rnE 'prefers-reduced-motion|useReducedMotion|motion-reduce' --include='*.tsx' --include='*.css' . | grep -v node_modules | grep -iE 'carousel|slide|gallery|lightbox' | wc -l
# walk each gallery and lightbox on a phone (slow network profile), a tablet, and a desktop; with keyboard only; with a screen reader; with reduced motion on; keep screenshots and the network waterfall
Methodology: Inventory the carousel, gallery, and lightbox components and the libraries behind them. Read auto-advance, pause, and stop behaviour, image sources, sizes, lazy loading, prefetch, and reserved dimensions. Read lightbox focus, close, scroll lock, and zoom handling, the address handling on open and close, and the gesture handling. Read alternative text sources, announcements, control names, indicators, and reduced motion. Then walk every gallery and lightbox on a phone with a slow network profile, a tablet, and a desktop, by touch, keyboard only, and with a screen reader, with reduced motion on, recording the waterfall, layout shifts, the back button and share address, and the announcements. Rank by the share of users meeting the component and whether the defect blocks viewing or navigation.
Control & Loading
- No auto-advance by default; where a carousel rotates, pause on hover, focus, and touch and a visible stop control; responsive sources with sizes per slot, lazy loading for off-screen slides, the next slide prefetched, thumbnails served at thumbnail size; dimensions or aspect ratios reserved so nothing shifts
Lightbox & Addresses
- A dialog with focus trapped and returned, escape and arrow keys, a close control inside the safe area, background scroll locked, pinch-zoom and pan contained; each open image reflected in the address so share, reload, and the back button work, with close returning to the gallery position
Gestures, Accessibility & Captions
- Swipe that does not fight the browser's back gesture or page scroll, with visible previous, next, and close controls as alternatives; meaningful alternative text per image, a position and count available to assistive technology without announcing every change, named controls, keyboard-reachable slides and thumbnails, labelled indicators with a way to jump; captions, credits, and counts shown in the lightbox
Motion, Performance & Orientation
- Transitions replaced with instant or fade changes under reduced motion; only nearby slides rendered for large sets, memory bounded, video slides muted and user-started; layout surviving rotation and resize with the current slide kept
Evidence rules: Confirmed requires the walk: the waterfall showing full-size loads, the layout shift measurement, the lightbox that did not close or trapped focus, the address unchanged on open, the back gesture triggered by a swipe, the alternative text as read, or the transition under reduced motion. A defect judged from the library's defaults alone is Likely until walked. Galleries that pass on every device and input are reported as such. Defer to the product's image pipeline for source generation, and say where the component needs sources it does not get.
Output Format
Start with a 3–5 line executive summary: galleries and lightboxes audited, auto-advance state, bytes loaded on open for the main gallery, lightbox and address behaviour, accessibility state, and the first fix.
Component table:
| Component | Auto-advance (pause, stop) | Responsive and lazy | Layout reserved | Lightbox (focus, close, zoom) | Address on open | Gestures with alternatives | Alternative text and announcements | Reduced motion | Status |
|---|
Findings: each with evidence, severity (Critical for lightboxes that trap or cannot be closed on phones, full-size loads of large sets on main pages; High for auto-advance without pause, no address on open, layout shift, missing alternative text; Medium for gestures, indicators, captions; Low for motion polish), and fix. Positive findings. Omit any section with nothing to report.
Want this applied to a live stack?
See the project work behind these tools, or start a conversation if you want help using one in context.