Building Block

Image Galleries

CSS Grid masonry, filterable portfolio grids, and full-screen lightboxes — lazy-loaded gallery patterns built with vanilla JS and no external libraries, deployable in a single Claude conversation.

Gallery patterns

Every gallery pattern uses native browser APIs — IntersectionObserver for lazy loading, CSS Grid for layout, vanilla JS for filtering and lightbox. No jQuery, no Fancybox, no Masonry.js.

Pattern 1 — CSS Grid Masonry Gallery

Auto-fill CSS Grid gallery with configurable tile widths. IntersectionObserver lazy loading defers off-screen images until they’re needed, keeping initial page load fast even for large collections.

CSS Grid IntersectionObserver Lazy Loading No Libraries
  • grid-template-columns: repeat(auto-fill, minmax(280px, 1fr))
  • IntersectionObserver swaps data-srcsrc on viewport entry
  • Low-quality placeholder: CSS blur filter on initial load, removed on img.load
  • Smooth opacity reveal transition once full image is ready
  • Alt-text enforced per image for accessibility and SEO
  • Responsive breakpoints: 1-column below 480px, 2-column below 768px, auto-fill above
  • Works with images in /assets/images/ or any absolute URL
Prompt to use with Claude

Build a CSS Grid masonry gallery page for my [photography / portfolio / product] site. Images are stored in /assets/images/gallery/ and named gallery-01.jpg through gallery-12.jpg. Use IntersectionObserver lazy loading with a blur placeholder. Auto-fill grid, minimum tile width 280px. Responsive: 1-col mobile, 2-col tablet, auto-fill desktop. CSS in theme.css, JS inline in the page.

Pattern 2 — Filterable Portfolio Grid

Gallery with category filter tabs above the grid. Clicking a tab shows only matching images using a CSS class toggle — smooth fade and scale transition with no layout shift during filtering.

Vanilla JS CSS Transitions Filter Tabs Accessible
  • Filter buttons above the grid, styled as pill tabs
  • Each image tagged with a data-category attribute (e.g. branding, web, print)
  • JS toggles .hidden class; CSS applies opacity:0; transform: scale(0.95) with transition
  • Active tab: accent underline and colour state
  • “All” tab shows everything; active by default on page load
  • Category list configured via data-category attributes in HTML only — no JS edits needed
  • Accessible: filter buttons are <button> elements with aria-pressed state
Prompt to use with Claude

Build a filterable portfolio gallery for my [design / photography / web] work. Categories: All, [Category 1], [Category 2], [Category 3]. Images in /assets/images/portfolio/ named port-01.jpg through port-09.jpg — assign 3 to each category. Filter tabs above the grid, pill style with orange active state. Fade + scale transition on filter change. CSS in theme.css, JS inline in the page.

Pattern 3 — Full-Screen Lightbox

Click any gallery image to open a full-screen lightbox with previous/next navigation, keyboard arrow key support, and touch swipe for mobile. No external library — vanilla JS only.

Vanilla JS Keyboard Nav Touch Swipe Focus Trap
  • Full-screen overlay: position:fixed; inset:0; z-index:9999
  • Previous/Next arrow buttons with keyboard arrow key equivalents
  • Close on Escape key or click outside the image
  • Touch swipe: tracks touchstart / touchend X delta, 50px threshold
  • Image counter label: “3 / 12” in monospace font, top-right corner
  • Focus trap while lightbox is open; focus returns to triggering element on close
  • role="dialog" and aria-modal="true" for screen reader compatibility
Prompt to use with Claude

Add a full-screen lightbox to my gallery page. Clicking any gallery image opens the lightbox. Previous/next buttons, keyboard left/right arrow navigation, Escape to close, click-outside to close, touch swipe support. Show image counter (e.g. “3 / 12”) top-right. Trap focus inside the modal. Return focus on close. Vanilla JS only. CSS in theme.css, JS inline in the page.

Every gallery pattern includes

Lazy loading built in

Off-screen images are deferred until they enter the viewport. Page load is fast even for galleries with dozens of high-resolution images.

No external libraries

All patterns use vanilla JS and CSS Grid only. No jQuery, no Fancybox, no Masonry.js — nothing to version-pin, update, or break.

Mobile and touch ready

Responsive grid breakpoints, touch swipe in the lightbox, and tap-friendly filter buttons. Works correctly on every device and screen size.

Accessible by default

Keyboard navigation, focus management, ARIA roles, and alt-text requirements are built into every pattern — not retrofitted afterwards.

Pair image galleries with

Combine galleries with these building blocks for a complete portfolio or creative site.

Hero Sections

Fullscreen, split-layout, and animated headline hero patterns for your gallery homepage.

View patterns

JS Animations

Add scroll-reveal and border-glow entry animations to your gallery grid and hero sections.

View patterns

Contact Forms

Enquiry forms and multi-step quote builders for photography and creative work.

View patterns

Deploy your first image gallery today

From £6.99/month. First month free — no credit card required.