Scroll Book Shelf Slide — Free HTML CSS JS Snippet

Scroll Book Shelf Slide · Scroll · Plain HTML, CSS & JS · Live preview

What's included

Features

Single GSAP scrub timeline sliced into per-book segments via position parameters
Book spines pivot with transform-origin: bottom center for a natural pull-forward motion
Pages panel scales open from scaleX(0.2) to scaleX(1) like a hinged cover
Fully reversible — scrubbed timeline plays backward cleanly on scroll-up
Warm wood-and-leather color palette via CSS custom property --hue per book
No pinning required — content scrolls through a tall section for a natural reading rhythm
Responsive book and panel sizing at the 640px breakpoint
Vertical writing-mode spine labels for an authentic bookshelf look

About this UI Snippet

Scroll Book Shelf Slide — GSAP Timeline Segments, Shelf Illustration & Content Panel Reveal

Screenshot of the Scroll Book Shelf Slide snippet rendered live

This snippet turns a row of styled div "book spines" into a scroll-driven storytelling shelf: as the user scrolls through a tall pinned-feeling section, each book in turn slides outward and tilts off the shelf while a hinged "pages" panel unfolds beside it to reveal a title and description, then both settle back before the next book takes its turn.

One shared scrub timeline, sliced into segments

A single GSAP timeline is attached to .shelf-wrap with scrollTrigger: { start: 'top top', end: 'bottom bottom', scrub: true }. Rather than creating one ScrollTrigger per book, the total scroll distance is divided into equal fractions — segStart = i / books.length and segEnd = (i + 0.85) / books.length — and each book's slide/tilt and its pages panel's open/close tweens are placed on the shared timeline at those absolute positions using GSAP's position parameter. This keeps every book perfectly in sync with scroll position without juggling multiple triggers.

The slide-and-tilt

Each .book is a narrow div styled as a spine with transform-origin: bottom center so it pivots naturally like a book being pulled forward. gsap.fromTo animates x, y and rotate from resting values to x: 34, y: -10, rotate: -7 — enough to read as "sliding outward and tipping" without leaving the shelf entirely.

The pages panel

The .pages div is absolutely positioned to the right of the spine with transform-origin: left center. It starts at opacity: 0, scaleX: 0.2, translated slightly left, then scales up to scaleX: 1 with full opacity — mimicking a book cover swinging open — timed to appear once the spine has slid far enough to have "room," and closing again as the segment ends so the effect fully reverses on scroll-up.

Fully reversible, no pinning required

Because everything lives on one scrubbed timeline keyed to scroll progress (not pin: true), scrolling back up smoothly reverses every book in sequence — GSAP scrub timelines are inherently bidirectional, so no manual reset logic is needed.

Pair this with Scroll Card Deck Shuffle for another sequential reveal pattern, or Scroll Polaroid Stack Flip for a similarly staggered "stack" story.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Paste this snippet's HTML, CSS and JS into an AI assistant and ask it to walk through why the segment boundaries are computed as i / books.length and (i + 0.85) / books.length rather than fixed pixel or percentage values — the answer touches on why fraction-based segmentation keeps the effect correct regardless of how many books you add or remove. It's also a good candidate to extend: ask the assistant to make the pages panel display a real cover image with a CSS 3D flip instead of a flat scale-open, to add a subtle shelf-dust parallax layer behind the books, or to convert the shelf into a horizontal-scroll gallery using the same segment-timeline technique paired with scroll-horizontal-pin.

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 scroll-driven "bookshelf" animation in HTML, CSS and JavaScript using GSAP and ScrollTrigger — no React, no canvas, no WebGL.

Requirements:
- Render a horizontal row of narrow div "book spine" elements sitting on a wooden shelf illustration built from CSS gradients, each spine a different flat color and each with a vertical text label (use CSS writing-mode).
- Give each book a hidden absolutely-positioned "pages" panel anchored to its right edge, starting scaled down and transparent with its transform-origin on the left edge so it can open like a hinged cover.
- Wrap the whole shelf in a tall section (several viewport heights) and attach exactly one GSAP timeline to it via ScrollTrigger with start 'top top', end 'bottom bottom', and scrub: true.
- Divide the timeline into one segment per book using fractions of the book count (segment i spans from i/total to (i+1)/total of the timeline), and within each book's segment: slide and rotate the spine outward from the shelf using its own transform-origin at the bottom, then fade/scale open its pages panel, then close the panel and return the spine to rest before the next book's segment begins — placing every tween at its correct start time with GSAP's timeline position parameter.
- The entire effect must play forward and reverse cleanly as the user scrolls down and back up, since scrub ties it directly to scroll position with no manual state to reset.
- Use a warm library color palette: dark wood browns for the shelf and background, and a distinct accent hue per book spine.

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.

Source Code

<div class="hint">Scroll ↓ to pull books off the shelf</div>
<div class="shelf-wrap">
  <div class="shelf-stage">
    <div class="shelf-board"></div>
    <div class="books">
      <div class="book" data-title="Deep Work" style="--hue:210;--i:0">
        <span class="spine-label">Deep Work</span>
        <div class="pages">
          <h3>Deep Work</h3>
          <p>Rules for focused success in a distracted world. Cultivate the ability to concentrate without distraction on cognitively demanding tasks.</p>
        </div>
      </div>
      <div class="book" data-title="Atomic Habits" style="--hue:0;--i:1">
        <span class="spine-label">Atomic Habits</span>
        <div class="pages">
          <h3>Atomic Habits</h3>
          <p>An easy and proven way to build good habits and break bad ones. Tiny changes, remarkable results.</p>
        </div>
      </div>
      <div class="book" data-title="Sapiens" style="--hue:35;--i:2">
        <span class="spine-label">Sapiens</span>
        <div class="pages">
          <h3>Sapiens</h3>
          <p>A brief history of humankind, from foraging bands to the cognitive, agricultural and scientific revolutions.</p>
        </div>
      </div>
      <div class="book" data-title="The Design of Everyday Things" style="--hue:150;--i:3">
        <span class="spine-label">The Design of Everyday Things</span>
        <div class="pages">
          <h3>The Design of Everyday Things</h3>
          <p>Why some products satisfy customers while others frustrate them — the psychology of good design.</p>
        </div>
      </div>
      <div class="book" data-title="Thinking, Fast and Slow" style="--hue:275;--i:4">
        <span class="spine-label">Thinking, Fast and Slow</span>
        <div class="pages">
          <h3>Thinking, Fast and Slow</h3>
          <p>Two systems drive the way we think — fast, intuitive and emotional, versus slower, deliberate and logical.</p>
        </div>
      </div>
    </div>
  </div>
</div>

Step by step

How to Use

  1. 1
    Scroll through the previewScroll down slowly — each book spine slides forward and tilts while its content panel unfolds beside it, then both reset as the next book begins.
  2. 2
    Add or remove booksDuplicate a .book element inside .books with a unique --hue custom property for its spine color, a spine-label span, and a .pages panel with your own title/description.
  3. 3
    Tune the segment timingIn the JS panel, adjust segStart and segEnd (currently i/books.length and (i+0.85)/books.length) to control how much scroll distance each book gets and how much they overlap.
  4. 4
    Adjust the slide distance and tiltChange the x, y and rotate values inside the fromTo call to make the slide-off more or less dramatic.
  5. 5
    Restyle the shelfThe .shelf-board and .shelf-stage background gradients set the warm wood tone — swap the hsl() values or background gradient for a different library aesthetic.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component, or "Tailwind" for a React + Tailwind version.

Real-world uses

Common Use Cases

Book or product catalog storytelling
Use each "book" as a product or publication, revealing a description panel as users scroll through a catalog page.
Sequential feature reveal
Repurpose each book as a feature card in a numbered story, sliding out and opening to reveal a description one at a time.
Portfolio or case-study timeline
Each book becomes a project; the pages panel reveals project details as the visitor scrolls through your body of work.
Library or bookstore landing page
A literal bookshelf hero section for a reading app, library, or bookstore, introducing featured titles one by one.
Editorial long-form storytelling
Break a long article into "chapters" represented as books that open to reveal a summary as the reader scrolls.
Learn multi-segment scrub timelines
Study how segStart/segEnd position math divides one ScrollTrigger across many sequential animations without extra triggers.

Got questions?

Frequently Asked Questions

A single timeline scrubbed against one long .shelf-wrap section is more performant and keeps every book perfectly synchronized to scroll position. Each book's animation is placed on that shared timeline at a calculated fraction of the total duration using GSAP's position parameter.

Remove the final .to(pages, { opacity: 0 ... }) tween for that book's segment, or extend its segEnd close to 1 so it only closes near the very end of the section.

Yes — add an <img> inside .pages alongside or instead of the <p> text; the panel container already scales and fades in as a unit.

Because scrub: true ties the timeline's playhead directly to scroll position rather than firing a one-shot animation, GSAP automatically plays every tween in reverse as the user scrolls upward.

Any number — the segment math (i / books.length) automatically redistributes the available scroll distance evenly across however many .book elements exist.