# Horizontal Scroll Section

> A pinned editorial rail where vertical scroll sweeps through horizontal chapters with measured snap, counter-drift parallax, and a precise progress readout.

Canonical: https://gsapvault.com/effects/horizontal-scroll-section
Live demo: https://gsapvault.com/demos/horizontal-scroll-section/index.html

| Property | Value |
|----------|-------|
| Type | effect |
| Tier | paid |
| Price | £5 |
| Difficulty | intermediate |
| Plugins | ScrollTrigger |
| Techniques | horizontal-scroll, pinning, scrub, parallax, snap |
| Uses Lenis | Yes |

## Overview

A cinematic horizontal scroll section built on ScrollTrigger pinning. The section locks to the viewport while vertical input carries visitors through full-screen editorial chapters, then releases cleanly at the final panel. Panels can use any mix of widths; travel is measured from the track's real scrollWidth, keeping the sequence accurate through resizes, font loads, and content changes. Optional panel-edge snap, per-element parallax, progress bar, and chapter readout are driven by data attributes.

The demo places the rail inside an ordinary vertical page (an opening spread above it and a closing log below) because the turn from vertical to horizontal only reads as a turn if there is vertical scrolling on either side of it.

## Features

- Pinned horizontal scrolling driven by a single scrubbed x-position tween
- Variable-width panels: distance measured from scrollWidth, not panel counts
- Snap-to-panel edges with measured snap points that survive resizes
- Per-element parallax via containerAnimation ScrollTriggers
- Scroll progress bar plus nearest-panel readout updated without tween churn
- Fully responsive: functional end values plus invalidateOnRefresh
- Configurable scrub smoothing and traverse speed via data attributes
- Accessible: keyboard focus scrolls panels into view, reduced motion stacks panels vertically

## Use Cases

- Portfolio and case study galleries with a cinematic sideways flow
- Product feature walkthroughs that step through panels one by one
- Storytelling chapters and timeline sequences on landing pages
- Service or process breakdowns with numbered stages
- Award-style agency sites that need a memorable scroll moment

## Vibe-Code Ready Setup

This effect includes `START-HERE-AI.md`, a product-specific copy-paste setup prompt for Cursor, Claude Code, ChatGPT, GitHub Copilot, Windsurf, and other coding assistants. It tells the assistant to inspect the existing stack, integrate the supplied files, preserve the design, scope selectors, retain accessibility and responsive behaviour, add framework-appropriate GSAP cleanup, and report what it tested.

[How AI-assisted setup works](https://gsapvault.com/vibe-coding)

## How It Works

ScrollTrigger pins the section with pin: true and scrubs a single gsap.to tween that translates the track by scrollWidth minus the viewport width. Both the tween's x value and the trigger's end are functions, so combined with invalidateOnRefresh every resize re-measures the layout. Snap points are computed from each panel's offsetLeft on refresh and resolved through gsap.utils.snap. Parallax layers use containerAnimation ScrollTriggers tied to the main tween, and the progress bar is updated in onUpdate through a cached gsap.quickSetter.

## Integration Preview

How this effect integrates into a page. The full documentation (examples, events, programmatic API, customization guide) ships with the download.

### Quick Start

**1. Add to your HTML `<head>`:**

```html
<link rel="stylesheet" href="path/to/style.css">
```

**2. Add before closing `</body>` tag:**

```html
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/ScrollTrigger.min.js"></script>
<script src="path/to/script.js"></script>
```

**3. Add the effect HTML anywhere in your `<body>`:**

```html
<section class="hscroll" data-hscroll aria-label="Horizontal gallery">
  <div class="hscroll-track">
    <article class="hscroll-panel">Panel 1</article>
    <article class="hscroll-panel">Panel 2</article>
    <article class="hscroll-panel">Panel 3</article>
    <article class="hscroll-panel">Panel 4</article>
  </div>
</section>
```

That's it. The section pins when it reaches the top of the viewport and the track translates left as the user scrolls down, releasing when the last panel arrives.

### Options

All options are data attributes on the `[data-hscroll]` element unless noted.

| Attribute | Values | Default | Description |
|-----------|--------|---------|-------------|
| `data-hscroll` | - | required | Marks the section to pin and scroll horizontally |
| `data-hscroll-scrub` | number, `true` | `1` | Scrub smoothing in seconds. `true` locks the track 1:1 to scroll with no smoothing |
| `data-hscroll-snap` | `true`, `false` | `false` | Snap the track to the nearest panel's left edge when scrolling stops |
| `data-hscroll-speed` | number | `1` | Traverse speed multiplier. `2` crosses the track in half the scroll distance, `0.5` doubles it |
| `data-hscroll-parallax` | number | `0.2` (when present) | On any element **inside a panel**: drifts it against the track direction as its panel crosses the viewport. Higher = faster drift |
| `data-hscroll-progress` | - | optional | On an element inside the section: its `scaleX` is driven from 0 to 1 as the track traverses |
| `data-hscroll-readout` | - | optional | Displays the nearest panel number as a zero-padded value (`01`, `02`, etc.) |
| `data-hscroll-total` | - | optional | Displays the total panel count as a zero-padded value |

### Accessibility

- **Reduced motion**: with `prefers-reduced-motion: reduce`, the section is not pinned; panels stack vertically as normal page content. This is enforced twice: a CSS `@media` fallback (works even without JavaScript) and a `gsap.matchMedia()` branch that adds `.hscroll--static`
- **Keyboard navigation**: focusable content inside panels stays reachable. A `focusin` listener on the track converts the focused panel's position into the matching page scroll position, so tabbing into an off-screen panel scrolls the pinned section to reveal it (using `lenis.scrollTo` when Lenis is present)
- **Focus visible**: `:focus-visible` styles on buttons match `:hover`
- **Semantics**: give the section an `aria-label`; decorative parallax numbers use `aria-hidden="true"`

#### Reduced Motion Behavior

When `prefers-reduced-motion: reduce` is set:
- No pinning, no horizontal translation, no parallax
- Panels display stacked vertically at full width
- The progress bar is hidden

### Browser Support

Modern browsers (ES6+). Not compatible with IE11.

### Dependencies

**Required:**
- GSAP 3.12+
- ScrollTrigger plugin

**Optional:**
- Lenis (smooth scroll integration; effect works without it)

## What You Get

- `index.html`: working demo page
- `assets/script.js`: commented, readable source
- `assets/style.css`: effect styles
- `README.md`: full documentation with examples and framework integration notes
- `START-HERE-AI.md`: product-specific copy-paste prompt for AI-assisted setup
- `LICENSE.txt`: standard license terms
- Lifetime updates: re-download anytime from your library

## Get the Code

This is a premium effect. The standard license costs £5 one-time and covers unlimited personal and commercial projects with no attribution required. The only restrictions: no redistribution of the code itself and no competing effect libraries.

- [Buy Horizontal Scroll Section](https://gsapvault.com/effects/horizontal-scroll-section)
- [Effects & Templates Vault (£39 one-time, best value): every current and future effect and template](https://gsapvault.com/effects)

## Judge the Code Quality First

These related effects are free with complete source published, written to the same production standard (cleanup functions, reduced-motion support, framework-agnostic):

- [Scroll Progress Indicator](https://gsapvault.com/effects/scroll-progress.md): A precise GSAP reading-progress instrument with bar, ring, side rail, percentage, and active chapter feedback.
- [CSS Scroll Reveal](https://gsapvault.com/effects/css-scroll-reveal.md): Native CSS scroll-driven reveals for crisp fade, slide, and scale entrances with accessible static fallbacks and no animation JavaScript.
- [Parallax Hero](https://gsapvault.com/effects/parallax-hero.md): A pinned hero that separates its background photograph, copy, and foreground card into distinct scroll depths from a single scrubbed ScrollTrigger.

---

From [GSAP Vault](https://gsapvault.com): production-ready GSAP animation effects. Full catalog for agents: https://gsapvault.com/llms-full.txt
