MotionFlow logo

Parallax Animation

Create smooth, depth-based parallax motion that responds naturally to scrolling. MotionFlow’s parallax system moves elements at different speeds relative to the scroll position, creating a strong sense of depth without layout shifts or performance overhead.

# Getting started

Enable parallax movement on any element using the data-mf-parallax attribute. The element moves continuously in response to scrolling, creating a natural depth effect.

No initialization required. No configuration required. No JavaScript required.

Demo
Parallax
<div data-mf-parallax>Parallax</div>

MotionFlow automatically detects these attributes and applies smooth parallax movement in response to scrolling.

# Parallax attributes

MotionFlow parallax is attribute-driven. All single-element parallax behavior can be controlled directly from HTML using data-mf-parallax-* attributes.

Demo
Parallax
<div 
 data-mf-parallax
 data-mf-parallax-speed="1.5"
 data-mf-parallax-speed-tablet="1.25"
 data-mf-parallax-speed-mobile="1"
>
Parallax
</div>

You don’t need to add every attribute. MotionFlow has default values for all attributes. Default values are listed in the table below. Add an attribute only when you want to override the default.

AttributeDefaultDescription
data-mf-parallaxEnables scroll-based parallax movement on the element
data-mf-parallax-speed1Controls parallax speed on desktop screens
data-mf-parallax-speed-tablet0Overrides parallax speed on tablet screens
data-mf-parallax-speed-mobile0Overrides parallax speed on mobile screens
data-mf-parallax-ignoreExcludes the element from all parallax calculations

For staggered parallax groups and child-specific controls, refer to the Stagger documentation below.

# Parallax speed

Control how fast an element moves relative to scroll using data-mf-parallax-speed.

Parallax speed defines how strongly an element reacts to scroll. It applies to individual elements and works as a multiplier, not a pixel value.

Positive values move elements in the scroll direction, negative values move them in the opposite direction, and a value of 0 disables parallax entirely.

Demo
-2
0
2
<div data-mf-parallax data-mf-parallax-speed="-2">Speed = -2</div>
<div data-mf-parallax data-mf-parallax-speed="0">Speed = 0</div>
<div data-mf-parallax data-mf-parallax-speed="2">Speed = 2</div>

Lower values create subtle depth, while higher values create stronger parallax movement. Negative values reverse the direction of motion.

AttributeDefaultDescription
data-mf-parallax-speed1Controls how strongly an element reacts to scroll (acts as a multiplier)

Device behavior: Once you set data-mf-parallax-speed, it becomes the fallback for all devices. To control tablet or mobile behavior independently, you must explicitly set data-mf-parallax-speed-tablet and data-mf-parallax-speed-mobile.

# Responsive parallax speed

MotionFlow allows you to define different parallax speeds for desktop, tablet, and mobile devices.

This helps fine-tune motion intensity across screen sizes and avoid excessive movement on smaller devices.

Demo
Adaptive speed
No parallax
<div
  data-mf-parallax
  data-mf-parallax-speed="1"
  data-mf-parallax-speed-tablet="1.5"
  data-mf-parallax-speed-mobile="2"
>
  Adaptive speed
</div>

<div
  data-mf-parallax
  data-mf-parallax-speed="0"
  data-mf-parallax-speed-tablet="0"
  data-mf-parallax-speed-mobile="0"
>
  No parallax
</div>

Setting tablet or mobile speed to 0 disables parallax on that device size, while keeping it active on other screen sizes.

AttributeDefaultDescription
data-mf-parallax-speed-tablet0Parallax speed applied on tablet screens
data-mf-parallax-speed-mobile0Parallax speed applied on mobile screens

Fallback behavior: If a device-specific speed attribute is not provided, MotionFlow uses the closest available speed — tablet falls back to desktop, and mobile falls back to tablet first, then desktop.


## Breakpoints

Breakpoints define when MotionFlow switches between desktop, tablet, and mobile parallax values.

These thresholds are evaluated on resize and determine which speed value is applied.

MotionFlow.init({
  parallax: {
    breakpoints: {
      mobile: 768,   // ≤ 768px → mobile settings
      tablet: 1024   // ≤ 1024px → tablet settings
    }
  }
});
DeviceDefault breakpoint
Mobile768px
Tablet1024px

If no device-specific speed is defined, MotionFlow falls back to the nearest available value. To fully disable parallax on a device, explicitly set its speed to 0.

# Parallax stagger

Create layered depth effects across multiple elements using data-mf-parallax-stagger.

Each direct child is automatically assigned its own parallax speed, creating a natural depth progression while scrolling.

Demo
1.0
1.8
2.6
<div
  data-mf-parallax-stagger
  data-mf-parallax-stagger-speed="1"
  data-mf-parallax-stagger-step="0.8"
>
  <div>Speed 1.0</div>
  <div>Speed 1.8</div>
  <div>Speed 2.6</div>
</div>

Parallax stagger applies movement to all direct children of the container. The first child uses the stagger speed, and further children increase or decrease their speed based on the step value.

AttributeDefaultDescription
data-mf-parallax-staggerEnables staggered parallax behavior for all direct children
data-mf-parallax-stagger-speed0Base parallax speed used as the starting point for staggered children
data-mf-parallax-stagger-speed-tablet0Base stagger speed applied on tablet screens
data-mf-parallax-stagger-speed-mobile0Base stagger speed applied on mobile screens
data-mf-parallax-stagger-step0.3Speed increment added between each staggered child
data-mf-parallax-stagger-step-tablet0.2Speed increment between children on tablet screens
data-mf-parallax-stagger-step-mobile0.1Speed increment between children on mobile screens
data-mf-parallax-stagger-directionleftControls how stagger order is calculated (left, right, or center)
data-mf-parallax-stagger-ignoreExcludes a specific child element from stagger calculation

Child speeds are calculated incrementally, starting from the first child and progressing based on the step value.

ChildResulting speed
1st1.0
2nd1.8
3rd2.6

# Stagger speed

Stagger speed defines the parallax speed of the first child inside a stagger group.

Each subsequent child increases or decreases its speed based on the stagger step value.


## Default stagger speed

By default, the stagger speed is set to 0. This means the first child will not move unless you explicitly define a stagger speed or apply a non-zero stagger step.

DeviceDefault first-child speedUsageDescription
Desktop0data-mf-parallax-stagger-speed="0"Base parallax speed for the first child on desktop
Tablet0data-mf-parallax-stagger-speed-tablet="0"Base parallax speed for the first child on tablet
Mobile0data-mf-parallax-stagger-speed-mobile="0"Base parallax speed for the first child on mobile

## Global stagger speed configuration

You can define the default first-child stagger speed globally using MotionFlow configuration.

MotionFlow.init({
  parallax: {
    stagger: {
      speed: 0.8,        // First child speed (desktop)
      tabletSpeed: 0.4,  // First child speed (tablet)
      mobileSpeed: 0.2   // First child speed (mobile)
    }
  }
});

These values act as fallbacks and apply to all stagger groups unless overridden at the element level.


## Per-stagger speed configuration

You can define the first-child stagger speed directly on a stagger container using HTML attributes.

Fallback behavior (attributes): If a device-specific stagger speed attribute is not provided, MotionFlow falls back to the next available value — tablet falls back to desktop, and mobile falls back to tablet or desktop.

Demo
1.0
1.3
1.6
<div
  data-mf-parallax-stagger
  data-mf-parallax-stagger-speed="1"
  data-mf-parallax-stagger-step="0.3"
>
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</div>

## Relationship between stagger speed and step

Stagger speed defines the starting point (first child), while the stagger step defines how quickly depth increases or decreases across the group.

If the step is set to 0, all children will move at the same speed as the first child.

ConfigurationResult
speed: 1, step: 0All children move at speed 1
speed: 1, step: 0.3Depth increases progressively
speed: 1, step: -0.3Depth decreases progressively

# Stagger step

The stagger step controls how much the parallax speed changes between consecutive children inside a stagger group.

Each child receives its own calculated speed using the formula:

childSpeed = baseSpeed + (step × index)

Stagger step can be configured globally, per stagger group, and per device.


## Default step values

MotionFlow applies different default step values based on device size to ensure smooth and natural depth across screen sizes.

DeviceDefault stepUsageDescription
Desktop0.3data-mf-parallax-stagger-step="0.3"Speed increment between children on desktop
Tablet0.2data-mf-parallax-stagger-step-tablet="0.2"Speed increment between children on tablet
Mobile0.1data-mf-parallax-stagger-step-mobile="0.1"Speed increment between children on mobile

## Global stagger step configuration

You can override the default stagger step values globally using MotionFlow configuration.

MotionFlow.init({
  parallax: {
    stagger: {
      step: 0.6,        // Desktop step
      tabletStep: 0.3,  // Tablet step
      mobileStep: 0.15  // Mobile step
    }
  }
});

These values act as fallbacks and are applied to all stagger groups unless overridden at the element level.


## Per-stagger step configuration

You can define step values directly on a stagger container using HTML attributes.

Fallback behavior (attributes): If a device-specific stagger step attribute is not provided, MotionFlow falls back to the next available value — tablet falls back to desktop, and mobile falls back to tablet or desktop.

Demo
<div
  data-mf-parallax-stagger
  data-mf-parallax-stagger-step="0.4"
  data-mf-parallax-stagger-step-tablet="0.2"
  data-mf-parallax-stagger-step-mobile="0.1"
>
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</div>

## Positive vs negative step

The sign of the step value controls whether depth becomes stronger or weaker across the stagger group.

Step valueEffect
0.3Each next element moves faster (stronger depth)
-0.3Each next element moves slower (more subtle depth)
Demo
<div
  data-mf-parallax-stagger
  data-mf-parallax-stagger-speed="1"
  data-mf-parallax-stagger-step="-0.3"
>
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</div>

Negative step values are useful when you want a gradual, layered effect without aggressive depth jumps.

# Parallax stagger direction

Control where depth begins within a stagger group using data-mf-parallax-stagger-direction.

Direction controls the order in which calculated speeds are assigned to child elements — it does not change how the speed values themselves are calculated.

Demo
1
2
3
<div
  data-mf-parallax-stagger
  data-mf-parallax-stagger-direction="left"
>
  <div>Child 1</div>
  <div>Child 2</div>
  <div>Child 3</div>
</div>

Direction only affects which element receives which speed. The speed formula always remains:

childSpeed = baseSpeed + (step × index)


## Direction values

ValueUsageEffect
leftdata-mf-parallax-stagger-direction="left"Depth increases from the first child to the last
rightdata-mf-parallax-stagger-direction="right"Depth increases from the last child to the first
centerdata-mf-parallax-stagger-direction="center"Depth increases outward from the center element

# Ignore specific children in stagger

Use data-mf-parallax-stagger-ignore to exclude specific children inside a stagger group from receiving parallax movement.

This attribute only applies to elements that are direct children of adata-mf-parallax-stagger container.

Demo
Active
Ignored
Active
<div data-mf-parallax-stagger>
  <div>Active</div>
  <div data-mf-parallax-stagger-ignore>Ignored</div>
  <div>Active</div>
</div>

Ignored children are skipped during stagger speed calculation and remain completely static while other items animate.

AttributeUsageDescription
data-mf-parallax-stagger-ignoredata-mf-parallax-stagger-ignoreExcludes the child element from stagger parallax calculations

# Parallax lifecycle

Parallax works automatically in most cases. When elements are shown, hidden, resized, or added dynamically, you may need manual control.

MethodMethod callDescription
initMotionFlow.parallax.init();Initializes or re-initializes parallax using the last configuration
refreshMotionFlow.parallax.refresh();Re-scans parallax elements and recalculates positions and speeds
destroyMotionFlow.parallax.destroy();Destroys parallax without affecting other MotionFlow modules

## Example usage

When parallax elements are added dynamically (or when layout positions change), refresh parallax after the DOM update.

// Call this after dynamic content loads or layout changes
function onLayoutChange() {
  MotionFlow.parallax.refresh();
}

# Global configuration (optional)

MotionFlow parallax works out of the box with zero JavaScript configuration. By default, all parallax behavior is controlled using HTML attributes.

Global configuration is only required if you want to override default values or define shared settings (including stagger parallax).

Individual elements can always override global values using data-mf-parallax-* and data-mf-parallax-stagger-* attributes.

MotionFlow.init({
  parallax: {
    /* -------------------------------------------------
       Base Parallax (for [data-mf-parallax])
    ------------------------------------------------- */
    speed: 1,           // Default: 1      | Desktop parallax speed
    tabletSpeed: 0,     // Default: 0      | Tablet parallax speed
    mobileSpeed: 0,     // Default: 0      | Mobile parallax speed
    breakpoints: {
      mobile: 768,      // Default: 768    | ≤ 768px → mobile settings
      tablet: 1024      // Default: 1024   | ≤ 1024px → tablet settings
    },
    /* -------------------------------------------------
       Stagger Parallax (for [data-mf-parallax-stagger])
       - Applies parallax to each direct child
       - Child speed = baseSpeed + (step * index)
    ------------------------------------------------- */
    stagger: {
      speed: 0,         // Default: 0      | Desktop base speed for stagger group
      tabletSpeed: 0,   // Default: 0      | Tablet base speed for stagger group
      mobileSpeed: 0,   // Default: 0      | Mobile base speed for stagger group
      step: 0.3,        // Default: 0.3    | Desktop step between children
      tabletStep: 0.2,  // Default: 0.2    | Tablet step between children
      mobileStep: 0.1,  // Default: 0.1    | Mobile step between children
      direction: "left" // Default: "left" | left | right | center
    }
  }
});

If you don’t call MotionFlow.init(), MotionFlow automatically uses its built-in parallax defaults.