Bookshop Template Template
A complete one-page site for an independent bookshop, built around a spine wall: a shelf of art-directed CSS book spines where pulling one tips the book out in 3D and opens it on the table below, cover and staff blurb on facing pages.
About This Template
A production-ready one-pager for a neighbourhood bookshop, art-directed like the shop itself: a warm kraft-paper wall, cream book pages on it, near-black ink doing the reading, and one rubber-stamp red that only ever behaves like a rubber stamp. Every shop object is a designed piece of CSS - the book spines, the covers, the club's date-due slip - and the people are real: four warm, colour-graded photographs of the shop in use, mounted like prints on cream card with stamped captions, showing the browsing, the book club mid-discussion and Saturday storytime.
The signature is the spine wall. The shelf is a row of eight books, each spine its own tiny piece of design - different widths, heights, bindings and type treatments, like real jackets from different publishers. Pull a spine and the book tips out of the shelf in 3D, then lands open on the table below: the front cover on the left leaf, a staff-written blurb with the price on the right. Pull it again, press Escape, or choose "Put it back" and it slides home.
Around the wall the page stays in the shop's voice: staff picks that take a red STAFF PICK stamp on hover, a book club section with a library date-due slip stamped with the year's meetings, an events list with chairs-out-kettle-on copy, and a visit section that tells you to push the sticking door harder. Swap the titles, blurbs, dates and prices for your own stock and deploy the folder as static files - there is no build step.
What's Included
- Complete deployable one-page site: nav, hero, spine wall, staff picks, book club, events, visit, footer
- Signature spine wall: eight art-directed CSS book spines with varied widths, heights, bindings and type treatments - each one a designed object, no images anywhere
- Pull a spine and the book tips out of the shelf in 3D, then opens on the table below with its designed cover and a staff blurb on facing pages
- Fully keyboard accessible: every spine is a real button with aria-expanded and aria-controls, Escape puts the open book back and returns focus to its spine
- Eight designed book covers built from the same binding tokens as the spines - reskin the cloth colours and both change together
- Staff picks take a rubber STAFF PICK stamp that thunks in on hover and focus; on touch devices the stamp is simply there
- A book club section with a library date-due slip: the year's meetings stamped in mono, the next one stamped in red
- Four photographs of the shop in use - the front room, the browsing tables, the club, storytime - bundled as optimised, colour-graded WebP prints on cream mounts, swappable by dropping files into assets/img
- Five-token palette plus four book-cloth colours, all with RGB triples and a measured contrast table in the stylesheet header
- Degrades completely: with JavaScript off, all eight books read in full below the shelf like a plain catalogue
- Reduced motion keeps the wall fully working - books appear open instantly instead of travelling, via both the CSS media query and the matchMedia branch
- Lenis smooth scrolling wired in and fully optional
Perfect For
- Independent bookshops, secondhand and antiquarian dealers
- Record shops, game stores and anywhere else with shelves worth browsing
- Publishers and small presses presenting a season's list
- Authors showcasing a backlist with real blurbs
- Learning 3D CSS transforms driven by GSAP: a real, content-driven example of preserve-3d, rotationY and staged timelines
How It Works
Structure
One script initialises each section inside a single gsap.context with gsap.matchMedia, keyed only on reduced motion so exactly one branch runs on every device. Every querySelector is guarded, so any section - the picks, the club, the whole shelf - can be deleted and the rest keeps working. Reveal start states are double-gated behind a has-js class and the motion media query, so a blocked CDN or a reduced-motion preference both leave a complete static page.
The spine wall
Each book on the shelf is a button styled as a spine: a 3D object with preserve-3d, a front face carrying the jacket design and a page-block face hidden along its fore edge. Activating it builds one timeline: the spine tips forward with rotationY and a translateZ lift so the pages catch the light, the table card below grows open from height zero, and the cover leaf falls flat from an 84-degree rotationY like a book slapped open. A second activation, Escape, or the Put-it-back button runs the same journey home.
State and focus
One book is open at a time: opening a spine closes the current one first, aria-expanded tracks every button, and closing from the keyboard returns focus to the spine it came from. If the table sits below the fold when a book opens - common on phones - the page scrolls it into view through Lenis when present, native scrollIntoView otherwise.
Accessibility and reduced motion
Under reduced motion the wall keeps working - it is the shop's menu, not decoration - but books appear open instantly: the reduce branch never tweens, a CSS rule gives the pulled spine a static offset, and Lenis is never created. The staff-pick stamps switch from a hover animation to simply being present, both under reduced motion and on touch devices.
Without JavaScript
The shelf renders as a wall of designed spines and all eight books read in full below it, stacked in order like a printed catalogue - covers, blurbs and prices are plain markup throughout. The only thing that disappears is the Put-it-back button, which would have nothing to put back.