ZYVOPMulti-Platform Sync
SeriesAI NewsWhy ZyVOPJoin Discord
LoginGet Started
ZYVOPMulti-Platform Sync

The Developer Publishing Hub. Write once, publish everywhere, and make your work citation-ready with built-in SEO, AEO, and GEO discovery support. Zero reader paywalls.

Content

  • Categories
  • Tags
  • Badges
  • Leaderboard
  • Write Article
  • Newsletter

Company

  • About Us
  • Why ZyVOP
  • Developer API & CLI
  • Write for Us
  • Contact

Connect

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • DMCA Policy
  • Code of Conduct

© 2026 ZyVOP. Developer Publishing Hub.

Zero paywalls · Full content ownership
All systems operational
HomeMantine Parallax v3 — From Tilt Card to Interactive Card System

Mantine Parallax v3 — From Tilt Card to Interactive Card System

Giovambattista Fazioli
Giovambattista Fazioli
Senior Full-stack Engineer, Lead DeveloperSupport
September 4, 2026
5 min read
Mantine Parallax v3 — From Tilt Card to Interactive Card System
#performance#react#showdev#ui

Spring physics, gyroscope, glare effects, compound layers, keyboard accessibility, and a 60fps performance rewrite — all in one major release.

Introduction

Version 3.0.0 of @gfazioli/mantine-parallax is the biggest update since the package was first published. What started as a simple Apple TV-style tilt card has evolved into a full-featured interactive card system with physically-based animations, mobile device support, and first-class accessibility. Under the hood, the rendering pipeline has been completely rewritten to deliver smooth 60fps updates with zero unnecessary React re-renders.

This release adds 13 new features, fixes 5 bugs, and includes 4 performance/architecture improvements — while staying fully compatible with Mantine 8.x and React 19.


What's New

Parallax.Layer — Compound Component for Multi-Depth Parallax

The new Parallax.Layer compound component replaces the legacy contentParallax + cloneElement approach. Each layer moves independently based on a depth multiplier, giving you precise control over parallax intensity per element.

<Parallax><Parallax.Layer depth={1}>
    <Text>Background — subtle movement</Text></Parallax.Layer><Parallax.Layer depth={3}>
    <Title>Foreground — dramatic movement</Title></Parallax.Layer></Parallax>

Enter fullscreen mode Exit fullscreen mode

Layers automatically consume rotation state via React Context — no prop drilling, no cloneElement magic. The legacy contentParallax prop still works but Parallax.Layer is the recommended approach going forward.

Spring Physics Animation

Enable physically-based movement with overshoot and oscillation using a damped harmonic oscillator. The card feels alive — it bounces, settles, and responds organically to cursor movement.

<ParallaxspringEffectspringStiffness={150}  // higher = snappierspringDamping={12}     // higher = less bounce>{children}</Parallax>

Enter fullscreen mode Exit fullscreen mode

Spring parameters can be changed mid-animation — new values take effect immediately with no residual momentum from previous settings.

Glare Reflection Effect

A glare band follows the cursor across the card surface, simulating light reflecting off a glossy surface.

<ParallaxglareEffectglareColor="rgba(255, 255, 255, 0.4)"glareMaxOpacity={0.4}glareSize={30}glareOverlay>{children}</Parallax>

Enter fullscreen mode Exit fullscreen mode

Dynamic Shadow Effect

A shadow that shifts opposite to the card rotation, creating the illusion of a light source from above. The shadow updates at 60fps during hover and smoothly transitions back to zero on leave.

<ParallaxshadowEffectshadowColor="rgba(0, 0, 0, 0.4)"shadowBlur={30}shadowOffset={0.8}>{children}</Parallax>

Enter fullscreen mode Exit fullscreen mode

Gyroscope Support

On mobile devices, the card tilts based on physical device orientation via the DeviceOrientation API. On iOS 13+, permission is requested on the first user interaction — with built-in guards against duplicate permission prompts.

<ParallaxgyroscopeEnabledgyroscopeSensitivity={1}>{children}</Parallax>

Enter fullscreen mode Exit fullscreen mode

Keyboard Accessibility

Arrow keys tilt the card, Escape resets it. When enabled, the component adds proper ARIA attributes (tabIndex, role="group", aria-roledescription, aria-label) for screen reader support.

<ParallaxkeyboardEnabledkeyboardStep={5}  // degrees per key press>{children}</Parallax>

Enter fullscreen mode Exit fullscreen mode

Touch Support

Touch interactions are enabled by default. The card responds to finger movement on mobile, with touch-action: none on the outer container to prevent scroll interference.

<Parallax touchEnabled>{children}</Parallax>

Enter fullscreen mode Exit fullscreen mode

Mantine radius Prop

Standard Mantine radius prop for controlling border radius via the --parallax-radius CSS variable. Supports theme tokens, CSS strings, or pixel numbers.

<Parallax radius="md">...</Parallax><Parallax radius={16}>...</Parallax>

Enter fullscreen mode Exit fullscreen mode

Rotation Control Props

Fine-tune how the card responds to interaction:

<ParallaxresetOnLeave={false}    // card holds its tilt after mouse leaveinvertRotation           // card tilts away from cursormaxRotation={15}         // clamp rotation to ±15 degreeshoverScale={1.05}        // subtle scale-up on hover/>

Enter fullscreen mode Exit fullscreen mode

Transition Customization

Control the transition timing for enter/leave animations:

<ParallaxtransitionDuration={300}    // mstransitionEasing="ease-out" // any CSS easing function/>

Enter fullscreen mode Exit fullscreen mode

onRotationChange Callback

Subscribe to rotation changes for building synchronized UI — debug overlays, companion shadows, linked animations:

<ParallaxonRotationChange={({ rotateX, rotateY, isHovering }) => {
    console.log(`Tilt: ${rotateX.toFixed(1)}° × ${rotateY.toFixed(1)}°`);}}>{children}</Parallax>

Enter fullscreen mode Exit fullscreen mode

prefers-reduced-motion Support

The component automatically respects the OS-level reduced motion setting. All transitions, hover effects, spring animations, and touch/gyroscope interactions are disabled when active — no extra configuration needed.


Performance Rewrite

The internal architecture was rewritten from the ground up:

  • Native events + requestAnimationFrame: Replaced the useMouse hook (which triggered a React re-render on every pixel of mouse movement) with native onMouseMove/onTouchMove events throttled via requestAnimationFrame. Rotation updates are batched at 60fps with zero React re-renders during interaction.

  • GPU-friendly shadow updates: box-shadow CSS transitions — which are not GPU-accelerated and cause expensive repaints — are no longer applied during active hover. The shadow updates directly via RAF at 60fps. The CSS transition is only used on mouse leave for a smooth fade-out.

  • Mid-hover deactivation: If disabled or prefers-reduced-motion changes to true while the card is being hovered, the component now properly deactivates instead of continuing to process events.


Bug Fixes

  • Light effect persistence: The light gradient overlay no longer disappears from the DOM after mouse leave, preventing a flash when re-entering the card.

  • Background position conflict: Setting backgroundPosition without a backgroundImage no longer causes CSS shorthand/longhand conflicts with Mantine's bg prop in React 19.

  • Shadow during spring return: The dynamic shadow now follows the card rotation during spring return animation instead of snapping to zero instantly.

  • Spring parameter hot-swap: Changing springStiffness or springDamping mid-animation uses the new values immediately and resets accumulated velocity.

  • Gyroscope permission dedup: Rapid taps no longer trigger multiple permission prompts or register duplicate deviceorientation listeners.


Breaking Changes

1. New glare style selector

ParallaxStylesNames now includes 'glare' as a fourth selector. If you have exhaustive classNames or styles overrides:

// Before<Parallax classNames={{ root: '...', content: '...', light: '...' }} />

// After — add the glare key<Parallax classNames={{ root: '...', content: '...', light: '...', glare: '...' }} />

Enter fullscreen mode Exit fullscreen mode

2. New --parallax-radius CSS variable

The root element's border-radius is now controlled by a CSS variable. If you were overriding border-radius via styles, the CSS variable takes precedence — use the radius prop instead:

// Before<Parallax style={{ borderRadius: 16 }}>

// After
<Parallax radius={16}>

Enter fullscreen mode Exit fullscreen mode

3. New exports and factory type changes

ParallaxFactory now includes vars (ParallaxCssVariables) and staticComponents ({ Layer: typeof ParallaxLayer }). New exports: ParallaxLayer, ParallaxLayerProps, ParallaxProvider, useParallaxContext, ParallaxContextValue, ParallaxCssVariables.


Migration from contentParallax to Parallax.Layer

The legacy contentParallax prop still works, but Parallax.Layer is the recommended approach:

// Before (legacy)<Parallax contentParallax contentParallaxDistance={2}><div>Child 1</div><div>Child 2</div></Parallax>

// After (recommended)<Parallax><Parallax.Layer depth={2}>
    <div>Child 1</div></Parallax.Layer><Parallax.Layer depth={4}>
    <div>Child 2</div></Parallax.Layer></Parallax>

Enter fullscreen mode Exit fullscreen mode

Parallax.Layer gives you explicit control over each element's depth and works with any children — no cloneElement limitations.


New Props at a Glance

Prop

Type

Default

Description

springEffect

boolean

false

Enable spring physics animation

springStiffness

number

150

Spring snappiness

springDamping

number

12

Spring bounce reduction

gyroscopeEnabled

boolean

false

Enable device orientation tilt

gyroscopeSensitivity

number

1

Gyroscope rotation multiplier

keyboardEnabled

boolean

false

Enable arrow key interaction

keyboardStep

number

5

Degrees per key press

shadowEffect

boolean

false

Enable dynamic shadow

shadowColor

MantineColor

'rgba(0,0,0,0.4)'

Shadow color

shadowBlur

number

30

Shadow blur radius

shadowOffset

number

0.8

Shadow offset multiplier

glareEffect

boolean

false

Enable glare reflection

glareColor

MantineColor

'rgba(255,255,255,0.4)'

Glare color

glareMaxOpacity

number

0.4

Maximum glare opacity

glareSize

number

30

Glare band size

glareOverlay

boolean

true

Render glare above content

radius

MantineRadius

—

Border radius (theme tokens or px)

touchEnabled

boolean

true

Enable touch interactions

hoverScale

number

1

Scale factor on hover

resetOnLeave

boolean

true

Reset rotation on leave

invertRotation

boolean

false

Tilt away from cursor

maxRotation

number

—

Clamp rotation degrees

transitionDuration

number

300

Transition time in ms

transitionEasing

string

'ease-out'

CSS easing function

onRotationChange

function

—

Rotation change callback


Getting Started

# Install or update
npm install @gfazioli/mantine-parallax@3
# or
yarn add @gfazioli/mantine-parallax@3

Enter fullscreen mode Exit fullscreen mode

Import the styles in your app entry point:

import '@gfazioli/mantine-parallax/styles.css';

Enter fullscreen mode Exit fullscreen mode

Basic usage with the new features:

import { Parallax } from '@gfazioli/mantine-parallax';

function InteractiveCard() {return (
    <Parallax
      radius="md"
      springEffect
      glareEffect
      shadowEffect
      p={24}
      bg="dark.7"
    >
      <Parallax.Layer depth={1}>
        <Text c="dimmed">Background layer</Text>
      </Parallax.Layer>
      <Parallax.Layer depth={3}>
        <Title c="white">Foreground layer</Title>
      </Parallax.Layer>
    </Parallax>);}

Enter fullscreen mode Exit fullscreen mode


Links

  • npm package

  • Documentation & Live Demos

  • GitHub Repository

  • Mantine Extensions Hub

Comments (0)

Login to post a comment.

Giovambattista Fazioli
Giovambattista Fazioli

Senior Full-stack Engineer, Lead Developer

Italian Senior Full-stack Engineer and Lead Developer on the Cloud team at Namecheap. I build developer tools, React/Mantine UI components and native macOS apps — mostly open source. I work across TypeScript, Next.js, Go and SwiftUI, and I've been coding since the Commodore/Assembly days. Creator of WP Bones and 25+ Mantine extensions, and maintainer of the Undolog open-source studio.

Support
Subscribe to Giovambattista Fazioli's Newsletter

More from Giovambattista Fazioli

View profile

FinderGit 0.29.0 — open a commit like a folder

There’s a moment, reading a commit list, where you want to know one small thing: which files did that one touch?

3 minSep 4

Netfox 0.18.0 — is it my connection, or the internet?

There is a question that comes up every time something feels slow, and until now Netfox could not...

3 minSep 4

Mantine Book — Grab Any Edge, Turn Any Page

A realistic iBooks-style book for React built on Mantine: stack two-sided pages and turn them by...

5 minSep 4

Netfox — The macOS app that never loses track of your network

I built Netfox because every existing answer to "what's actually on my network?" annoyed me. The...

5 minSep 4

Audio That Sees Itself

A Mantine-native audio player for React with waveform visualisation and a live spectrum analyser,...

5 minSep 4