# Section Parallax

> Adds parallax background effects to Elementor Sections and Containers — scroll-driven movement of a background image at different speeds, plus the Pro-only mouse-tracked parallax mode.

**Class file:** `includes/Extensions/EAEL_Parallax_Section.php` (374 lines)
**Slug:** `section-parallax` (`config.php` `extensions` key)
**Public docs:** <https://essential-addons.com/elementor/docs/parallax-section/>
**Pro-shared:** ✅ Pro-only (Lite has Promotion teaser)

## Overview

Adds a "Parallax" panel under Section's Layout tab and Container's Layout tab. The user enables parallax, picks a background image, configures speed / direction / mobile behaviour.

Implementation is JS-driven — Pro injects data attributes during `after_render`, then `section-parallax.min.js` reads them and applies parallax transforms using **jarallax** + **jquery-parallax** + **GSAP**.

## Features

- **Scroll-parallax** — background image translates as the user scrolls
- **Mouse parallax** — background tracks mouse cursor
- **Per-axis configuration** — X / Y speed independently
- **Mobile disable** — turn off on small screens (perf)
- **Container support** — works on both legacy Sections and Elementor 3.x Flexbox Containers

## Pro vs Lite

| Capability | Lite | Pro |
| --- | --- | --- |
| Panel visible in editor | Teaser only | ✅ |
| Scroll-parallax | ❌ | ✅ |
| Mouse-parallax | ❌ | ✅ |
| Mobile disable toggle | ❌ | ✅ |

## File Map

| File | Role |
| --- | --- |
| `includes/Extensions/EAEL_Parallax_Section.php` | Class — controls + `after_render` attribute injection |
| `src/css/view/section-parallax.scss` → `assets/front-end/css/view/section-parallax.min.css` | Layer styling |
| `src/js/view/section-parallax.js` → `assets/front-end/js/view/section-parallax.min.js` | Frontend init |
| `assets/front-end/js/lib-view/gsap/gsap.min.js` | Animation engine |
| `assets/front-end/js/lib-view/jarallax/jarallax.min.js` | jarallax lib |
| `assets/front-end/js/lib-view/jquery-parallax/jquery-parallax.min.js` | jQuery parallax lib |

## Architecture

Constructor wires 4 hooks (`EAEL_Parallax_Section.php:18-23`):

```php
add_action( 'elementor/element/section/section_layout/after_section_end',   [ $this, 'register_controls' ], 10 );
add_action( 'elementor/frontend/section/after_render',                       [ $this, 'after_render' ], 10 );
add_action( 'elementor/element/container/section_layout/after_section_end', [ $this, 'register_controls' ], 10 );
add_action( 'elementor/frontend/container/after_render',                     [ $this, 'after_render' ], 10 );
```

Same control set registered against both element types; same `after_render` handler.

## Controls Reference

| Control id | Purpose |
| --- | --- |
| `eael_parallax_section` | Section header |
| `eael_parallax_enable` (or similar) | Master switch |
| Parallax type (scroll / mouse) | Configures behaviour |
| X/Y speed | Multipliers |
| Mobile disable | Skip on small viewports |

(Pro uses `eael_parallax_*` prefix — older convention, not `eael_ext_parallax_*`.)

## Behavior Flow

1. **Editor:** user enables parallax on a section. Sets image, speed, mode.
2. **Save:** settings persist.
3. **Frontend `after_render`:** Pro reads settings, appends data attributes to the rendered section wrapper.
4. **Frontend JS init (`section-parallax.min.js`):** scans for elements with parallax data attributes, calls jarallax / GSAP to bind scroll / mouse-move handlers.

## Hooks & Filters

### Elementor hooks consumed

| Hook | Method |
| --- | --- |
| `elementor/element/{section,container}/section_layout/after_section_end` | `register_controls` |
| `elementor/frontend/{section,container}/after_render` | `after_render` |

### Pro / EA hooks emitted

None visible. Implementation is self-contained.

## Asset Dependencies

| Asset | Type | Notes |
| --- | --- | --- |
| `section-parallax.min.css` | `self` | Layer styling |
| `gsap.min.js` | `lib` | GSAP animation |
| `jarallax.min.js` | `lib` | Primary parallax lib |
| `jquery-parallax.min.js` | `lib` | Fallback / additional modes |
| `section-parallax.min.js` | `self` | EA glue code |

All under `EAEL_PRO_PLUGIN_PATH`. Loaded only when a section/container on the page has parallax enabled (via `Asset_Builder`).

## Behavior Quirks

- **GSAP + jarallax both loaded.** Heavy combined payload (~120KB). Consider whether one would suffice for new feature work.
- **Mobile-disable toggle** is the user's responsibility — Pro doesn't auto-disable on small viewports
- **No `prefers-reduced-motion` check** — accessibility regression for users with motion sensitivity
- **Editor preview** may not animate identically to frontend; the JS bails or differs in edit mode

## Known Limitations / Gaps

1. No `prefers-reduced-motion` honour — flagged as a11y issue
2. Three libraries (GSAP + jarallax + jquery-parallax) is heavy for the feature
3. Lite-side teaser doesn't reflect Pro's mouse-parallax mode — user upgrades expecting one thing, gets two
4. No per-image performance fallback when the image is huge (>5MB)

## Code Pointers

- Constructor: `EAEL_Parallax_Section.php:17-24`
- Controls: `:25-end of register_controls`
- `after_render` attribute injection: `after_render` method

## Cross-References

- Architecture: [`docs/architecture/asset-loading.md`](../architecture/asset-loading.md)
- Shared patterns: [`_patterns.md`](_patterns.md)
- Rule: [`.claude/rules/asset-pipeline.md`](../../.claude/rules/asset-pipeline.md)
