Art Gallery Template

£10

A one-page site for a contemporary art gallery, built on a cool white ground with one vermilion, whose signature is a walk-the-wall exhibition: the section pins and vertical scroll pans a hang of CSS-drawn artworks sideways, with a medium filter that re-hangs the wall.

ScrollTriggerFlip Lenis advanced
5 more details
horizontal-scrollpinningfilterflip-layoutscroll-reveal
Art Gallery Template - website template preview

This template reads better at your own screen size than in the frame below:

About this template

A production-ready one-page site for a contemporary art gallery's current exhibition, built for a fictional Antwerp gallery, Verge. It runs on a cool white ground with near-black type and a single vermilion, the way a real white-cube space lets the work carry the colour.

Read the full template overview

The signature is walking the wall: the exhibition section pins, and scrolling down pans a hang of twelve artworks sideways, each an abstract composition drawn entirely in CSS and SVG, mounted and matted like framed work with the piece nearest the centre lifting as you pass. A medium filter re-hangs the wall on the fly, the departing works dissolving out while the pan resets to the first piece and a live count reports what is on view. A featured now-showing piece sits below and enlarges into a full-bleed view on Flip.

The page is structured the way a gallery talks about a show: the exhibition title and dates lead, the wall of work follows, then one piece in depth, the curatorial statement, and the practical visit details. Copy is written in a dry curatorial voice, and there is not a single external image or photograph to license, host, or replace.

Every colour resolves from a short token block, so the whole site reskins from a handful of values, and every section is guarded so a buyer can delete any of them and the rest still runs.

What's included

11 items
  • Complete deployable one-page site: sticky nav, type-led hero, walk-the-wall exhibition, featured piece, curatorial statement, visit details and footer
  • Signature walk-the-wall exhibition: the section pins and vertical scroll pans twelve framed artworks sideways, with the piece nearest the centre lifting as you pass and a progress bar tracking the walk
  • Every artwork is drawn in CSS and SVG, so there are no images to license, optimise, or host, and the page looks finished the moment it opens
  • Medium filter re-hangs the wall live: departing works dissolve out, the pan resets to the first piece and the length recomputes, with real aria-pressed controls and a live on-view count
  • Featured now-showing piece enlarges into a full-bleed view on Flip, dismissed by click, the close control, or the Escape key
  • Masked type reveal on the exhibition title, with the resting position pinned so nothing is left offset
  • Clean scroll-reveals bring each section in as it enters the viewport, pre-hidden before first paint so nothing flashes
  • Vermilion is held to large display type, marks, and UI because it is deliberately below the body-text contrast floor on this ground, and the token comment says so
  • Three-value token block plus RGB triples: change the ground, the ink, and the vermilion and the whole site reskins with no stray literals left behind
  • Lenis smooth scrolling wired in, kept in lockstep with the pinned wall, and fully optional
  • Accessible: the wall degrades to a native horizontal scroll strip under reduced motion and with no JavaScript, filtering still works, the featured piece enlarges without animation, and every artwork stays reachable with the filter controls simply absent

Perfect for

5 use cases
  • Contemporary art galleries and project spaces announcing a current exhibition
  • Museums, kunsthalles, and non-commercial spaces presenting a single show
  • Artist-run spaces and collectives that want a wall of work as the page's spine
  • Design studios, ceramicists, or makers presenting a catalogue of pieces filterable by type
  • Pop-up shows, degree shows, and fair booths that need a self-contained microsite with no image pipeline

How it works

5 sections

Structure

One script initialises each section with a single setup and teardown path and one motion branch, keyed only on reduced motion so exactly one branch runs on every device. Every section is found by a data attribute and guarded, so a buyer can delete the featured piece, the statement, or the visit block and the wall still filters. The artworks are markup, not images, so the page is a complete static document before any script runs.

Walking the wall

The exhibition section pins with ScrollTrigger and a scrubbed tween pans the track of works horizontally as you scroll down, so vertical travel reads as walking along a hang. The pan length is the track's own overflow, read from a function so it re-evaluates on resize and after a filter, and the pin starts below the fixed nav so the filter bar stays clear. On every update the work nearest the viewport centre gets an is-focus class and lifts, and a progress bar fills. Each work is an abstract composition of layered CSS gradients, clip paths and small SVG shapes, matted in a frame, with its title, artist, year and medium printed beneath where the text keeps its contrast.

Re-hanging the wall

Clicking a medium filter runs a short cross-dissolve: the track fades out, the works that do not match are dropped with an is-off class, ScrollTrigger.refresh recomputes the pan length for the new track width, the pan resets to the first work so a shorter wall can never strand you past its end, and the track fades back. A set small enough to fit centres itself and hides the progress bar and scroll hint, since there is nothing to pan. The filter buttons carry aria-pressed and a live region reports the new on-view count, so the active medium is exposed to assistive technology, not just shown.

The featured piece

The now-showing piece enlarges by moving the same element into a full-bleed overlay and Flipping it from its inline rectangle to the enlarged one, so it is one element that grows rather than a second copy appearing. A veil fades up behind it, and the view is dismissed by clicking the veil, pressing the close control, or hitting Escape, which Flips it back into the page. Focus is moved to the close control on open and returned to the trigger on close.

Reduced motion and no JavaScript

The wall is never pinned unless motion is allowed: its default CSS is a native horizontal scroll strip, so both reduced-motion and no-JavaScript visitors get the same wall of works, scrollable by hand. Under reduced motion filtering toggles instantly and the enlarge runs with no animation, and the CSS media query holds every reveal target visible. With no JavaScript the filter row and the enlarge control are hidden by CSS, all twelve artworks stay on the strip, and the featured piece sits at its inline size, so nothing on the page is ever reachable only through a script.

Plugins ScrollTrigger, Flip
Difficulty Advanced
Smooth scroll Lenis integration
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Questions about this template

Do I have to upload images of the artworks?

No, and that is the point of this one. All twelve works on the wall are drawn in CSS and SVG, so there is nothing to license, optimise or host, and the page looks finished the moment it opens. For a pop-up, degree show or fair booth with no image pipeline, that removes the whole asset problem.

Can I put photographs of real work in instead?

Yes, the frames take images. You would be swapping the drawn plate inside each frame; the pan, the centre lift and the filter all work on the frames rather than their contents. Budget for consistent grading across the twelve, because a wall shows mismatched shots up immediately.

How does horizontal scrolling work on a phone?

It does not hijack. Under reduced motion and with JavaScript off the wall degrades to a native horizontal scroll strip, so it is a normal swipeable row rather than a pinned section fighting the page. Filtering still works and every artwork stays reachable.

What does the medium filter do to the wall?

It re-hangs it live: departing works dissolve out, the pan resets to the first piece and the scroll length recomputes so the walk still ends where it should. The controls are real aria-pressed buttons with a live on-view count.

Can I sell work through it?

No, there is no checkout. It is an exhibition announcement site: current show, featured piece, curatorial statement and visit details. Commercial galleries generally handle sales by enquiry anyway, and the structure suits non-commercial spaces and artist-run projects equally.

Paid template

Purchase to unlock the code.

Buying Art Gallery Template opens the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects.

£10 Standard license, unlimited projects

Browse free effects

Documentation

Quick Start

  1. Copy the whole folder to your project. It is static: no build step.
  2. Open index.html. Replace the gallery name (Verge), the exhibition (Interval), the artwork captions, the curatorial copy, and the visit details with your own.
  3. Deploy the folder as-is. The GSAP and Lenis tags load from a CDN; nothing else is required.

The scripts at the end of <body> are:

Code snippet omitted: it ships with the download.

Sections & options

Every section is found by a data-* hook and guarded independently, so you can delete any one and the rest still runs.

Section Hook Notes
Nav [data-nav] Sticky, translucent. Edit the links inline.
Hero [data-hero] The exhibition title ([data-line]) rises on a masked reveal; the sub-copy, facts and figure ([data-intro]) fade in with it.
Exhibition wall [data-wall], [data-gallery], [data-viewport], [data-track] The signature. See below.
Featured piece [data-feature] Enlarges on Flip. See below.
About / statement [data-about] Curatorial text and a pull quote.
Visit [data-visit] Hours, address, admission.
Footer Wordmark, links, contact.

The exhibition wall

The section pins and vertical scroll pans the track of works ([data-track]) sideways, so scrolling reads as walking the hang. The pan length is the track's own horizontal overflow, read live so it re-evaluates on resize and after a filter, and the pin starts below the fixed nav so the filter bar stays clear. The work nearest the viewport centre gets is-focus and lifts; [data-progress] fills as you go. This is motion only: with no JavaScript or under reduced motion the same track is a native horizontal scroll strip you swipe by hand, so nothing is trapped behind the pin.

Each work is a <figure data-work data-medium="…"> with a .work-frame (the mat), a decorative .art .art--N composition, and a caption. Works carry a size class (is-sm / is-md / is-lg) for the hang's rhythm. To add a work, copy any figure, give the .art a new art--N block in style.css, set data-medium to one of the filter values, and pick a size class.

The filter buttons carry data-filter matching those data-medium values (all, painting, paper, sculpture, textile). To add a medium: add a data-medium to some works and a matching <button data-filter="…"> to [data-filters]. Nothing else is wired by index; the script pairs them by value.

Clicking a filter runs a short cross-dissolve: the track fades out, non-matching works get is-off, the pan length is recomputed for the new track width, the pan resets to the first work, and the track fades back. A set small enough to fit centres itself and hides the progress bar and scroll hint. [data-wall-count] reports the on-view count via aria-live.

The featured piece

[data-feature-open] moves [data-feature-piece] into [data-feature-target] in the overlay and Flips it from its inline rectangle to the enlarged one — it is one element growing, not a copy. Dismiss with the veil, the close control, or Escape; focus returns to where it was. Swap the featured artwork by changing the .art--feature block in style.css and the caption text in the feature-text and lightbox-cap.

Palette

The whole site is three colours at different values, plus greys for text. Change these tokens in :root (assets/style.css) and keep each -rgb triple in step with its hex, and the site reskins with no stray literals left behind.

Code snippet omitted: it ships with the download.

Measured contrast (as used, on the #F2F2EF ground)

Pair Ratio Where
--ink on ground 15.8:1 all body copy and headings
--dim on ground 5.05:1 ledes, captions, secondary text
--faint on ground 4.8:1 smallest labels, years, notes
ground on --ink 15.8:1 featured band and footer
--faint-ink on --ink 6.8:1 footer meta, address

All body and label text clears the 4.5:1 AA floor at its actual size.

Vermilion is deliberately not a text colour. --accent measures 3.77:1 on the ground and 4.23:1 as white-on-vermilion — both below the 4.5:1 body floor. It is used only for:

  • the hero display word (Interval), which is ~6rem, so the 3:1 large-text rule applies and it clears at 3.77:1;
  • marks and rules (the diamond brand mark, the eyebrow ticks, the active-filter underline), which are non-text UI at the 3:1 bar;

and never for body copy, captions, small labels, or button text. Buttons are ink, not vermilion, for the same reason. If you swap in a lighter accent, keep it off small text or darken it (past roughly #C7331C) before using it as type.

Accessibility

  • Reduced motion: the wall is never pinned — its default CSS is a native horizontal scroll strip — so the exhibition stays a swipeable wall of works. A CSS media query holds every reveal target visible, filtering toggles instantly, and the enlarge runs with no animation.
  • No JavaScript: the filter row, the on-view count, and the enlarge control are hidden by CSS (.has-js gates them). All twelve works stay on the horizontal strip, and the featured piece sits at its inline size. Nothing is reachable only through a script.
  • Filters are real <button>s with aria-pressed; the active medium is exposed to assistive technology, not just shown by the underline.
  • The enlarged view is a labelled role="dialog"; focus moves to the close control on open and returns on close, and Escape dismisses it.
  • Keyboard focus is visible throughout via :focus-visible.

Dependencies

  • GSAP 3.15.0 core, ScrollTrigger, and Flip
  • Lenis 1.3.17 smooth scroll (optional — remove the block in script.js and the CDN tag to drop it)
  • Google Fonts: Rozha One (display) and Hind (body)

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.

Your cart

Your cart is empty

The Vault £99

Everything in the catalogue, plus everything we release next.