Parallax Hero Section — Free HTML CSS JS Snippet

Parallax Hero Section · Scroll · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Lerp-smoothed cursor tracking
currentX and currentY close 6% of the gap to targetX/targetY per frame — exponential ease-in that gives layers physical inertia and smooth deceleration.
Five independent depth layers
Stars, sky gradient, distant mountains, closer hills, and anchored content each have independent xFactor/yFactor — add layers by appending to the array.
SVG mountain and hill silhouettes
Vector shapes with preserveAspectRatio="xMidYMax slice" fill the hero at any resolution without pixelation. Two mountain polygons create depth with opacity layering.
Procedural star field
120 SVG circles with randomised position, size, and opacity are generated in JS — no image asset required. Stars appear in the far-background layer.
Device tilt support
DeviceOrientationEvent feeds gamma and beta values into the same target variables as mouse events — the parallax works by tilting on mobile.
prefers-reduced-motion support
The rAF animation loop is skipped entirely when reduced motion is preferred. Layers render at translate(0,0) — no layout shift.
Gradient headline with clip
background-clip: text applies an indigo→slate gradient to the headline text — a zero-image technique for gradient typography.
Scroll hint animation
An animated mouse-scroll icon fades up from below after 1.5s, prompting users to scroll. Uses a CSS-only @keyframes scrollDot loop.

About this UI Snippet

Parallax Hero — Mouse-Driven Layered Parallax, Lerp Smoothing & SVG Depth Layers in Vanilla JS

Screenshot of the Parallax Hero Section snippet rendered live

A parallax hero section creates the illusion of depth by moving background layers at different speeds as the cursor moves — slower layers feel farther away, faster layers feel closer. This snippet builds a five-layer parallax hero (stars, sky gradient, distant mountains, closer hills, anchored content) driven by mouse position and lerp smoothing, with device tilt support for mobile and a prefers-reduced-motion fallback — all in pure HTML, CSS, and vanilla JavaScript.

Parallax effects are one of the defining techniques of motion-rich web design — they appear on SaaS landing pages, game sites, portfolio headers, and interactive storytelling pages. The key challenge is making them feel smooth and physical rather than choppy or nauseating. This snippet solves that with linear interpolation (lerp) smoothing, SVG vector layers that scale to any resolution, procedural star generation, and device orientation support for mobile — all in under 80 lines of vanilla JavaScript.

Multi-layer depth using xFactor / yFactor per layer

The parallax effect is defined by a layers array where each entry has an element reference and two factors: xFactor and yFactor. The layer closest to the viewer (hills) has the highest factors (0.07, 0.05), while the farthest layer (stars) has the lowest (0.01, 0.01). When the cursor is at centre-relative offset (targetX, targetY), each layer's transform is set to translate(targetX * xFactor, targetY * yFactor) — multiplying by a small factor converts the full cursor travel range (~600px on a 1200px screen) into a subtle layer offset (hills move ~42px max at factor 0.07). Adding more layers is just adding one more entry to the array with the element and desired factors.

Lerp smoothing for physical feel

The cursor offset is not applied directly to the layers — that would produce jerky, latency-sensitive motion. Instead, targetX and targetY record where the cursor is, while currentX and currentY are the values currently applied to the layers. A requestAnimationFrame loop runs lerp(current, target, 0.06) each frame — linear interpolation at 6% per frame. This means the current value closes 6% of the remaining gap every ~16ms, producing an exponential ease toward the target. At 60fps, the layers "chase" the cursor with a natural deceleration, feeling physical and weighty.

SVG layers for resolution-independent depth

The mountain and hill shapes are inline SVGs with preserveAspectRatio="xMidYMax slice" and width:100%; height:100%, so they fill their container and crop rather than letterbox at any viewport size. The mountain SVG uses two <polygon> elements at different opacities for a layered ridge effect. The hill layer uses a <path> with bezier curves for smooth organic slopes. Because these are vector shapes, they scale sharply to any screen density — no raster image artifacts.

Procedural star generation

120 stars are generated programmatically in JavaScript using document.createElementNS to build SVG <circle> elements with random positions, radii (0.3–1.8px), and opacities (0.2–0.8). This avoids embedding a data URI or loading an image just for star dots. Because stars are in their own layer with the lowest parallax factor, they drift almost imperceptibly — giving a sense of immense distance.

Device orientation and reduced motion

On mobile devices that support the DeviceOrientation API, gamma (left-right tilt, scaled ×8) and beta (front-back tilt, scaled ×4) are fed into the same targetX/targetY variables. The lerp loop smooths the noisy gyroscope data automatically. If prefers-reduced-motion: reduce is set, the animation loop is never started and all layers remain at translate(0,0).

Step by step

How to Use

  1. 1
    Load the snippetPaste the HTML, CSS, and JS into your page. A deep-space hero appears with gradient sky, SVG mountain silhouettes, a star field, and centred headline and CTA buttons.
  2. 2
    Move the cursor slowly across the heroThe layers drift at different speeds — stars barely move while the hills follow the cursor more closely, creating a convincing 3D depth illusion.
  3. 3
    Observe the lerp smoothingWhen you stop the cursor, the layers continue drifting momentarily before settling — the exponential lerp easing gives each layer physical inertia.
  4. 4
    Move the cursor off the heroAll layers smoothly return to their centre positions as targetX and targetY reset to 0 and the lerp loop runs them back.
  5. 5
    Test on mobile (tilt)On a device that supports DeviceOrientationEvent, tilting the phone left-right and forward-back drives the parallax layers.
  6. 6
    Customise content and layersEdit the .hero-content HTML for your own headline and CTAs. Adjust xFactor/yFactor in the layers array to change depth intensity per layer.

Real-world uses

Common Use Cases

SaaS product landing pages
A parallax hero is the highest-impact "wow moment" on a marketing page — it signals quality and interactivity within the first second. Pair with a stats card section below.
Developer portfolio headers
Replace a static hero with a parallax scene that responds to cursor movement — a strong visual demonstration of front-end skill. Add a typewriter effect to the headline.
Game or app launch pages
Games and creative apps benefit from an immersive hero that establishes the visual world before the user even clicks. Add character sprites as additional layers, or compare with a video background hero if you prefer motion footage over vector layers.
Event or conference headers
A parallax landscape with mountains and sky creates a natural scene for outdoor, adventure, or technology events. Customise the SVG shapes to match the event theme.
Interactive storytelling intros
Use layered parallax to establish a narrative scene — a city skyline, a forest, or an abstract space — before scrolling into the story content.
Agency and studio showcase pages
Creative agencies use parallax heroes to demonstrate motion design capability to potential clients. The GPU-composited transforms keep it at 60fps.

Got questions?

Frequently Asked Questions

Add a new div.layer in the HTML with a unique ID and place your content (SVG, image, or CSS pattern) inside it. Add a matching entry to the layers array in JS with the element reference and your chosen xFactor/yFactor values. Lower factors = further away. Use z-index in CSS to control the stacking order.

Yes. Replace the mousemove handler with a scroll event listener that sets targetY = window.scrollY * -0.3 (for example). The lerp loop smooths the scroll updates. For CSS-only scroll parallax, use transform: translateY(var(--scroll-y)) with the new CSS animation-timeline: scroll() API.

The .hero-content div is outside the layers array and has no transform applied to it — it stays anchored in the centre. The pointer-events:none on .hero-content ensures mouse events pass through to the hero container, which handles the mousemove listener for the layers below.

Yes. Use the JSX, Vue, Angular, or Tailwind export buttons on this page. In React, set up the lerp rAF loop in useEffect and write transforms directly to DOM elements via refs — do NOT use useState for per-frame updates or you'll trigger thousands of re-renders per second. Return cancelAnimationFrame from the useEffect cleanup. In Vue, use onMounted/onUnmounted; in Angular, ngAfterViewInit/ngOnDestroy.

Add a scroll listener on the window alongside the mousemove listener. On scroll, update targetY += window.scrollY * scrollFactor (where scrollFactor is small, like 0.1). The lerp loop handles both inputs simultaneously — you don't need a separate loop.