046

Page Turn Book

£10 or the whole Vault, £99

A GSAP page-turn effect with curved paper, moving highlights and momentum. Drag or flick through a lookbook, with touch and arrow-key controls.

DraggableInertiaPlugin advanced
6 more details
page-turn3d-transformsdraggablemomentumpointer-effectsmicro-interaction

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

Released

About this effect

A page-turn effect that bends the paper instead of rotating it flat. Each leaf is laid out as a row of vertical strips positioned along a fold polyline, so as you drag, the page curls around a moving cylinder, a specular band travels down the fold, and a cast shadow slides across whatever is underneath.

Read the full effect overview

Draggable drives the turn and InertiaPlugin throws it: a lazy nudge springs back, a firm drag commits to the next spread, and a hard flick riffles two or three pages over in sequence. Nothing is a fixed animation, so the page sits wherever your hand left it.

Page Turn Book - GSAP animation effect preview

What's included

8 items
  • Real cylindrical curl built from vertical strips chained along a fold polyline, not a flat rotateY
  • Per-strip Lambert shading, so the highlight travels down the fold and the reverse side reads darker
  • Cast shadow that tracks the leading edge across the page below and crosses to the facing page mid-turn
  • InertiaPlugin throw with page snapping: nudge and it springs back, flick and it commits
  • Riffle on a hard flick, carrying two or three leaves over in a staggered cascade
  • Backface content revealed through the turn, so the reverse of each leaf is a real page
  • Single-page phone layout hinged on the left edge, with the strip count reduced automatically
  • Prev/next controls, arrow-key paging and a live region announcing the current spread

Perfect for

5 use cases
  • Fashion lookbooks and seasonal catalogues where the artefact is the pitch
  • Digital magazine and zine issues that want the object to feel bound
  • Restaurant and bar menus, where turning a page beats scrolling one
  • Product brochures and press kits presented as a flipbook
  • Portfolio case studies paced one spread at a time

How it works

3 sections

Each leaf is cloned into a row of strips, every strip holding a clipped copy of both faces. On each frame the script walks the strips as a polyline: strip i is placed where strip i-1 ended, rotated by a hinge angle plus a bend that swells through the middle of the turn, so the sheet stays joined while it curves.

Shading comes from a Lambert term against each strip's own normal, which flips past upright so the reverse of the page is lit differently. Strip widths are CSS custom properties, so a resize only re-measures rather than rebuilding.

Draggable runs on an off-document proxy with a snap function, letting InertiaPlugin project the flick before deciding which page it lands on. Strips are built lazily the first time a leaf moves, and the flat faces are swapped back in the moment it settles so the type stays crisp.

Plugins Draggable, InertiaPlugin
Difficulty Advanced
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this effect's demo, from the latest scan. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

Paid effect

Purchase to unlock the code.

Buying Page Turn Book 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. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

£10 Standard license, unlimited projects

Browse free effects

Or the whole library: the Vault, £99, one payment.

Documentation

Quick Start

1. Add to your HTML <head>:

Code snippet omitted: it ships with the download.

2. Add to your <body>:

Code snippet omitted: it ships with the download.

3. Add before the closing </body> tag:

Code snippet omitted: it ships with the download.

Using It With Your Own Design

What the effect actually requires of your markup:

  • [data-turn-book] on the outer element. It is the drag trigger and the element the perspective is applied through.
  • [data-turn-leaf] on each turnable leaf, each containing exactly one [data-turn-face="front"] and one [data-turn-face="back"].
  • Leaves must be absolutely positioned at the spine with transform-origin: 0 50%. That is what they rotate about, and it is the one piece of CSS the maths assumes rather than measures.
  • Page width is read from the first leaf's offsetWidth. Give leaves a real width, not auto.

What is only this demo's styling and can be deleted: everything on .page, .plate, .caption, .notes, .idx, .pull, .colophon, .fin, .masthead, and the whole cream-paper palette. None of it is queried by the script. Your faces can contain anything: images, video posters, a full CMS-rendered article.

Non-obvious CSS the effect depends on:

  • perspective on an ancestor of the leaves, and transform-style: preserve-3d on the book, the block, each leaf and each strip. Losing it anywhere in that chain flattens the curl into a plain rotation.
  • backface-visibility: hidden on the flat faces, so a turned leaf shows its reverse rather than a mirrored front.
  • The .turn-strip .turn-strip__side > * rule. Strips hold copies of your faces, so any transform, rounding, shadow or backface-visibility you put on a face has to be cancelled there or it is re-applied inside every strip. If you restyle the faces, keep that rule.
  • Rules aimed at the flat faces must use the child combinator (.leaf[data-turn-leaf-state='turning'] > .leaf__face). A descendant selector also hits the copies inside the strips.
  • overflow: hidden on the book in single-page mode. With no facing page to land on, the leaf swings off the side and has to be clipped.

Images: set draggable="false" on any <img> inside a leaf. Dragging across an image otherwise starts the browser's native drag, which fires pointercancel and kills the turn mid-gesture.

Options

Set on the [data-turn-book] element.

Attribute Values Default Description
data-turn-strips number 18 Strips the leaf is cut into. More is a smoother curl and more DOM. Narrow screens cap this at 9.
data-turn-curl degrees 55 How far the free edge leads the spine at the middle of the turn. 0 is a flat rotating plane, 30 is card, 55 is magazine stock, past 80 it creases.
data-turn-riffle true | false true Whether a hard flick carries extra leaves over with it.
data-turn-invite true | false true The one unprompted peel on load that shows the page is grabbable.

Optional child hooks: [data-turn-prev], [data-turn-next], [data-turn-status] (live region, gets "Spread 2 of 5").

Accessibility

  • Arrow keys and Page Up/Down turn the page whenever the book has focus; :focus-visible draws a ring on it.
  • The prev/next buttons are real <button>s and are disabled at each end of the book.
  • [data-turn-status] is a polite live region announcing "Spread 2 of 5" after every turn.
  • The turn is decorative. All content sits in the flat faces in the DOM and is readable with JavaScript off.

Reduced Motion Behaviour

Under prefers-reduced-motion: reduce the drag is not wired up and no strips are built. The buttons and arrow keys still work; they change the spread instantly instead of performing the turn. Nothing is hidden and nothing is left mid-animation.

Performance Notes

  • Strips are built the first time a leaf moves, not up front. A four-leaf book with 18 strips would otherwise clone eight pages of markup 18 times before the visitor has touched anything.
  • While a leaf is flat, its strips are display: none and nothing is written per frame. The flat faces are swapped back in the moment it settles, so resting type is never a stack of clipped copies.
  • Strip widths are CSS custom properties on the book, so a resize re-measures two values instead of rebuilding the rig.
  • Per frame the script writes one transform and one gradient per strip. At the default 18 strips that is 36 style writes, which is why the strip count is capped rather than left open.

Dependencies

  • GSAP 3.15.0
  • Draggable
  • InertiaPlugin

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