Source Code

<div class="pf-stage">
  <div class="pf-book" id="pfBook">
    <div class="pf-spine"></div>
    <div class="pf-pages" id="pfPages"></div>
  </div>
  <div class="pf-controls">
    <button type="button" class="pf-btn" id="pfPrev" aria-label="Previous page">‹</button>
    <span class="pf-count" id="pfCount"></span>
    <button type="button" class="pf-btn" id="pfNext" aria-label="Next page">›</button>
  </div>
</div>

Page Flip — CSS 3D Book Page Turn HTML CSS JS

Page Flip · Animations · Plain HTML, CSS & JS · Live preview

What's included

Features

Spine-edge rotation
Pages use transform-origin: left so they swing around the spine like real pages.
Real 3D depth
perspective + preserve-3d make the turn read as depth, not a flat flip.
backface-visibility hiding
The reverse of a turning page is hidden, so text never shows mirrored.
Per-flip z-index
Stacking is updated each flip so the turning page stays above its neighbours.
Front-to-back stack
Pages render with the first on top so the book reads naturally.
Forward, back & click
Prev/next buttons plus click-to-turn, all from one flipped count.
Position counter
Shows the current page out of the total, with controls disabled at the ends.
Content-driven & no library
Renders from a PAGES array in plain HTML/CSS/JS — zero dependencies.

About this UI Snippet

Page Flip — CSS 3D Book Where Pages Turn Around the Spine

Screenshot of the Page Flip snippet rendered live

A page-flip turns a stack of panels into a book whose pages rotate around the spine when you advance — a tactile, skeuomorphic way to present sequential content like a guide, a story, or a photo book. This snippet builds it with pure CSS 3D transforms and a little vanilla JavaScript for navigation, no library and no images.

Pages rotate around the spine edge

Each page is absolutely stacked and given transform-origin: left center, so rotating it with rotateY(-180deg) swings it around its left (spine) edge like a real page turning. A perspective on the book and transform-style: preserve-3d on the stack make the rotation read as genuine depth rather than a flat flip. A CSS transition animates the turn, so each flip is a smooth half-circle swing.

backface-visibility hides the reverse

Without backface-visibility: hidden, you'd see each page's content mirrored through the paper as it passes 90° — the text reversed and backwards. Hiding the backface means a turning page shows nothing on its reverse, which is what real (opaque) paper does. This single property is the difference between a convincing page turn and a broken-looking flip, the same trick behind flip cards and coins.

z-index managed per flip

The subtle but essential detail is stacking order. Pages render with the first on top (descending z-index), so the book reads front-to-back. As pages flip, their z-index is updated: turned pages drop behind while the current page stays on top — so the page mid-turn always sits above its neighbours and lands correctly on the "left" side of the book. Getting this z-index bookkeeping right is what stops pages from clipping through each other during the animation.

Forward, back, and click-to-turn

Next and Previous buttons turn pages in either direction (disabled at the first and last), a counter shows the position, and clicking the book itself advances — the natural gesture. All of it derives from one flipped count through update(), so the visuals, z-index, and controls stay consistent. Flipping back reverses the same transform smoothly.

Drop-in and adaptable

Pages come from a PAGES array, so it's content-driven — put chapters, onboarding steps, a lookbook, or a photo album in the pages. Restyle the paper, spine, and size to taste. It's a complete, dependency-free reference for CSS 3D page-turn mechanics: spine-edge rotation, backface hiding, and per-flip stacking.

Why CSS transforms instead of canvas

Many page-turn effects on the web reach for canvas or WebGL to draw a curling, paper-bend mesh, trading simplicity for vertex math and per-frame redraws. This snippet stays on the CSS transform pipeline instead — rotateY runs on the compositor thread, so the flip stays smooth even on low-end devices, and the whole effect is under a hundred lines of CSS with zero canvas redraw cost. The trade-off is a rigid page rather than a curling one: there's no paper-bend simulation, only spine rotation. For book-like UIs — FAQs, slideshows, manuals — a rigid flip reads just as convincingly and ships with far less code. The perspective: 1600px on .pf-book and the .7s cubic-bezier(.4,0,.2,1) transition were tuned so the turn looks weighty rather than rushed; a tighter perspective value exaggerates the 3D distortion near the spine, while a much larger one flattens the rotation toward a parallel-projection flip with little visible depth.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't have to visualize the 3D stacking order in your head. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to walk through exactly why update recomputes each page's z-index every time flipped changes, and what would visually break if that per-flip z-index bookkeeping were removed while pages still rotated with rotateY. The same assistant can help you optimize it, for example asking whether keeping every page fully in the DOM at once (rather than lazily rendering only nearby pages) is worth the tradeoff once a book grows to hundreds of pages. It's also useful for extending the effect: ask it to add a subtle drag-to-flip gesture using pointer events instead of only button clicks, curve the page edge with an extra transform during the rotation for a less rigid look, or support two-page spreads that flip together. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a "page flip" book effect in plain HTML, CSS, and JavaScript using CSS 3D transforms — no canvas, no WebGL, no page-curl library.

Requirements:
- A stack of absolutely positioned page elements inside a container with CSS perspective set, and preserve-3d on the stack so rotations show real depth.
- Every page must have transform-origin set to the left edge (the spine) and backface-visibility hidden, so rotating a page swings it around its left edge like a real page turning and its reverse side is never visible showing mirrored content.
- Flipping a page forward must apply a rotateY transform of negative 180 degrees via a CSS transition (not a JS-driven animation loop), so the turn animates smoothly as a half-circle swing.
- Track how many pages have been turned as a single count variable. On every change to that count, recompute every page's z-index: pages already turned must drop behind (low z-index), pages not yet turned keep a descending z-index so the first untouched page stays on top, ensuring the currently turning page is never visually clipped by its neighbors.
- Provide a Next button, a Previous button, and clicking the book itself to advance, all driving the same single count variable, with Next/Previous disabling appropriately at the first and last page.
- Render the pages' content (title and body text) from a plain JavaScript array of objects rather than hardcoding each page's markup, and show a "page X of Y" counter that updates as pages turn.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA small book renders with stacked pages and prev/next controls.
  2. 2
    Turn pagesClick Next (or the book) to flip a page around the spine; Previous flips back.
  3. 3
    Watch the positionThe counter shows the current page out of the total.
  4. 4
    Swap in your contentReplace the PAGES array with your own { title, text } (or richer markup).
  5. 5
    Resize the bookChange the .pf-book width/height (and perspective) to fit your layout.
  6. 6
    Restyle itAdjust the paper colour, spine, and shadows to match your theme.

Real-world uses

Common Use Cases

Guides and tutorials
Present steps as a flippable book — pair with a multi-step modal for a wizard variant.
Lookbooks and catalogs
Flip through product pages or a photo album, alongside a photo gallery.
Storytelling and onboarding
Turn intro content into a tactile reading experience.
Recipe and instruction cards
Page through steps like a recipe book.
Portfolios and case studies
Present work as turnable pages.
Learning CSS 3D transforms
A reference for spine rotation and backface hiding — compare with a 3D flip card.

Got questions?

Frequently Asked Questions

Each page has transform-origin: left center, so when it's rotated with rotateY(-180deg) it pivots around its left edge — the spine — swinging across like a real page rather than spinning about its centre. A perspective on the book and preserve-3d on the page stack give the rotation real depth, and a CSS transition animates the half-circle turn smoothly.

As a page rotates past 90°, its back faces you. Without backface-visibility: hidden, the browser shows the page's content mirrored through the back — reversed, backwards text — which looks broken. Hiding the backface makes the reverse of a turning page render as nothing, mimicking opaque paper. It's the same essential property used in flip cards and coin flips.

Pages start with the first on top via descending z-index, so the book reads front-to-back. On each flip, update() recomputes z-index: already-turned pages drop to low z-index (behind), while un-turned pages keep high z-index, and the page currently turning stays above its neighbours. Without this per-flip bookkeeping, pages would clip through each other mid-turn or land in the wrong order.

Yes. Each page is a normal flex container, so you can put headings, paragraphs, images, or any markup inside. For a two-page-spread look you'd render left and right halves; for image pages, drop an <img> in. Keep heavy content reasonable since all pages are in the DOM at once, but for a typical book of a few dozen pages it's fine.

Render pages from an array and hold the flipped count in state; derive each page's flipped class and z-index from it. In React use useState; in Vue a ref with computed classes; in Angular a property with class/style bindings. The 3D transform CSS and z-index logic are framework-agnostic — only the flipped state and click handlers move into the framework.