Mouse Parallax Scene
Un paysage de nuit en quatre plans, étoiles, lune, montagnes violettes et sapins, qui glissent à des vitesses différentes selon la position du pointeur : les sapins bougent six fois plus que les étoiles, et la profondeur apparaît d'elle-même — souris, stylet ou glissé du doigt, plusieurs scènes par page, paysage immobile si l'utilisateur réduit les animations.
Mis à jour le
Cet effet est gratuit — la catégorie 3D en contient 50 au total, dont 8 gratuits. Effect.Labs regroupe 840 effets vanilla. Découvrir la catégorie →
Exemples d'usage
Bibliothèque de Saint-Firmin
Veillée contes pour les 6-10 ans
Samedi 18 h, apportez un plaid
Les Amis des oiseaux du bocage
La Nuit de la chouette
Sortie nocturne d'écoute, rendez-vous 20 h 30 au lavoir
Comment ça marche
La racine .fx-0021-root (250 px de haut, fond rgb(26, 26, 36)) contient .parallax-scene, marquée data-parallax-scene : toute la largeur, 250 px de haut, ciel en dégradé #0a0a2e → #1a1a4e → #2a1a3e, coins de 12 px. Elle empile quatre .parallax-layer qui débordent de 30 px de chaque côté (inset: -30px), pour que leurs bords ne se voient pas quand ils glissent. Du fond vers l'avant : huit étoiles de 3 px (data-depth="0.1"), une lune de 60 px à halo doré à 30 px du haut et 60 px de la droite (0.25), quatre montagnes triangulaires indigo et violettes de 90 à 130 px de haut (0.4), sept sapins #064e3b de 40 à 70 px (0.6).
Le script parcourt toutes les racines .fx-0021-root de la page et branche une instance par scène. À chaque mouvement du pointeur, il mesure l'écart avec le centre de la scène et déplace chaque plan de cet écart multiplié par sa profondeur et par 0,5 : pointeur au bord gauche d'une scène de 560 px, les sapins glissent de 84 px, les montagnes de 56, la lune de 35, les étoiles de 14. Mesuré dans Chromium 151, Firefox 153 et WebKit 26.5 avec le pointeur à 5 % du coin haut gauche : 75,6 px en largeur et 33,8 px en hauteur pour les sapins. Une transition de 0,1 s lisse le mouvement ; quand le pointeur sort, tous les plans reviennent en place. Ce ne sont que des translations à plat : aucune 3D, rien qu'un parent puisse aplatir.
Deux choix tiennent le décor quand il bouge. Le pied des montagnes est posé 24 px sous le bord bas et celui des sapins 6 px sous le bord, avec une bande de sol sombre (#022c22, 64 px) cachée sous les sapins : quand le pointeur monte et que les plans remontent, le sol suit au lieu de laisser voir le ciel sous les arbres. Le script écoute les événements pointer plutôt que la souris seule : au doigt, touch-action: pan-y laisse défiler la page verticalement, et un glissé de côté fait jouer la profondeur ; le paysage revient en place quand le doigt se lève.
Accessibilité
- Mouvement réduit : sous
prefers-reduced-motion: reduce, un bloc limité à.fx-0021-rootimposetransform: noneaux quatre plans et retire leur transition : le paysage reste dans sa position de repos, lune, montagnes et sapins visibles. Mesuré dans Chromium, Firefox et WebKit : aucun déplacement sous la souris (75 px sans la préférence). - Décor : la scène ne contient aucun texte ni aucune commande, il n'y a rien à atteindre au clavier : son état de repos se lit tel quel. Si vous posez un titre ou un bouton par-dessus, comme dans les scènes ci-dessus, placez-le dans
.parallax-scene: il reste cliquable et le paysage continue de suivre le pointeur quand il le survole. - Lecteurs d'écran : les plans sont des
divvides, ignorés. Si l'illustration a un sens (un lieu, une sortie de nuit), dites-le dans le texte de la page, pas dans le décor. - Contraste : un texte blanc sur le ciel
#1a1a4ereste très lisible ; près des montagnes et des sapins, ajoutez un fond sombre semi-transparent sous le texte, comme dans la deuxième et la troisième scène.
Compatibilité navigateur
CSS (transform: translate, transition, triangles en bordures, touch-action) + JS d'événements pointer, aucune dépendance. Mesuré dans Chromium 151, Firefox 153 et WebKit 26.5 : mêmes décalages, deux scènes indépendantes sur une page, paysage immobile sous mouvement réduit ; glissé au doigt mesuré dans Chromium en mode tactile. Aucune 3D CSS ici : le rendu WebKit est fiable, mais un vrai Safari et un vrai iPhone n'ont pas été vérifiés.
Sans JavaScript, le paysage s'affiche dans sa position de repos, sans mouvement. Sur un écran tactile, un simple appui ne déplace rien : il faut glisser le doigt de côté.
Le code
Copiez les trois blocs dans votre page. Aucune dépendance.
<div class="fx-0021-root">
<div class="parallax-scene" data-parallax-scene>
<div class="parallax-layer" data-depth="0.1">
<div class="parallax-stars">
<span class="parallax-star" style="top:10%;left:15%"></span>
<span class="parallax-star" style="top:20%;left:75%"></span>
<span class="parallax-star" style="top:35%;left:45%"></span>
<span class="parallax-star" style="top:15%;left:90%"></span>
<span class="parallax-star" style="top:50%;left:25%"></span>
<span class="parallax-star" style="top:8%;left:55%"></span>
<span class="parallax-star" style="top:42%;left:80%"></span>
<span class="parallax-star" style="top:28%;left:10%"></span>
</div>
</div>
<div class="parallax-layer" data-depth="0.25" style="display:flex;align-items:flex-start;justify-content:flex-end;padding:60px 90px 0 0;">
<div class="parallax-moon"></div>
</div>
<div class="parallax-layer" data-depth="0.4">
<div class="parallax-mountains">
<div class="parallax-mountain mountain-1"></div>
<div class="parallax-mountain mountain-2"></div>
<div class="parallax-mountain mountain-3"></div>
<div class="parallax-mountain mountain-4"></div>
</div>
</div>
<div class="parallax-layer" data-depth="0.6">
<div class="parallax-trees">
<div class="parallax-tree tree-sm"></div>
<div class="parallax-tree tree-lg"></div>
<div class="parallax-tree tree-md"></div>
<div class="parallax-tree tree-sm"></div>
<div class="parallax-tree tree-lg"></div>
<div class="parallax-tree tree-md"></div>
<div class="parallax-tree tree-sm"></div>
</div>
</div>
</div>
</div>
.fx-0021-root,
.fx-0021-root *,
.fx-0021-root *::before,
.fx-0021-root *::after {
box-sizing: border-box
}
.fx-0021-root {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 250px;
overflow: hidden;
position: relative;
background: rgb(26, 26, 36);
color: rgb(255, 255, 255);
font-family: sans-serif;
}
.parallax-scene {
width: 100%;
height: 250px;
position: relative;
overflow: hidden;
border-radius: 12px;
background: linear-gradient(180deg, #0a0a2e 0%, #1a1a4e 50%, #2a1a3e 100%);
cursor: crosshair;
/* Touch: a sideways drag moves the layers, a vertical swipe still scrolls the page */
touch-action: pan-y;
}
.parallax-layer {
position: absolute;
inset: -30px;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.1s ease-out;
will-change: transform;
}
.parallax-stars {
width: 100%;
height: 100%;
}
.parallax-star {
position: absolute;
width: 3px;
height: 3px;
background: white;
border-radius: 50%;
opacity: 0.6;
}
.parallax-moon {
width: 60px;
height: 60px;
background: radial-gradient(circle at 35% 35%, #fef3c7, #fbbf24);
border-radius: 50%;
box-shadow: 0 0 40px rgba(251, 191, 36, 0.4), 0 0 80px rgba(251, 191, 36, 0.2);
}
/* The layers overflow the scene by 30 px on every side: the mountains stand 24 px below
the bottom edge, the trees 6 px below, so both stay visible when the layers move */
.parallax-mountains {
position: absolute;
bottom: 6px;
width: 120%;
left: -10%;
}
.parallax-mountain {
position: absolute;
bottom: 0;
width: 0;
height: 0;
border-style: solid;
}
.mountain-1 {
left: 5%;
border-width: 0 80px 120px 80px;
border-color: transparent transparent #1e1b4b transparent;
}
.mountain-2 {
left: 25%;
border-width: 0 100px 100px 100px;
border-color: transparent transparent #2e1065 transparent;
}
.mountain-3 {
left: 55%;
border-width: 0 90px 130px 90px;
border-color: transparent transparent #1e1b4b transparent;
}
.mountain-4 {
left: 75%;
border-width: 0 70px 90px 70px;
border-color: transparent transparent #2e1065 transparent;
}
.parallax-trees {
position: absolute;
bottom: -40px;
width: 120%;
left: -10%;
display: flex;
justify-content: space-around;
align-items: flex-end;
/* Ground strip under the trees, hidden below the edge at rest: it shows when the trees rise */
padding-bottom: 64px;
background: linear-gradient(to top, #022c22 64px, transparent 64px);
}
.parallax-tree {
width: 0;
height: 0;
border-style: solid;
border-color: transparent transparent #064e3b transparent;
}
.tree-sm {
border-width: 0 12px 40px 12px;
}
.tree-md {
border-width: 0 16px 55px 16px;
}
.tree-lg {
border-width: 0 20px 70px 20px;
}
/* Reduced motion: the landscape stays still in its rest position */
@media (prefers-reduced-motion: reduce) {
.fx-0021-root .parallax-layer {
transform: none !important;
transition: none;
}
}
(function() {
// ========== SPATIAL DEPTH ==========
// ==========================================
// 1. Mouse Parallax Scene (pointer events: mouse, pen and touch)
// One instance per .fx-0021-root: several scenes on one page each move on their own.
// ==========================================
document.querySelectorAll('.fx-0021-root').forEach(function(root) {
var scene = root.querySelector('[data-parallax-scene]');
if (!scene) return;
var layers = scene.querySelectorAll('.parallax-layer');
scene.addEventListener('pointermove', function(e) {
var rect = scene.getBoundingClientRect();
var centerX = rect.width / 2;
var centerY = rect.height / 2;
var mouseX = e.clientX - rect.left - centerX;
var mouseY = e.clientY - rect.top - centerY;
layers.forEach(function(layer) {
var depth = parseFloat(layer.getAttribute('data-depth')) || 0.1;
var moveX = mouseX * depth * 0.5;
var moveY = mouseY * depth * 0.5;
layer.style.transform = 'translate(' + moveX + 'px, ' + moveY + 'px)';
});
});
scene.addEventListener('pointerleave', function() {
layers.forEach(function(layer) {
layer.style.transform = 'translate(0, 0)';
});
});
});
})();
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Vitesse de chaque plan (HTML — data-depth des .parallax-layer) |
0.1, 0.25, 0.4, 0.6 | Plus le nombre est grand, plus le plan bouge et plus il paraît proche. Gardez un écart net entre plans voisins ; un plan à 0 reste fixe (utile pour un titre). |
Amplitude générale (JS — 0.5 dans moveX et moveY) |
0.5 | Multiplie tous les déplacements. À 0.3, l'effet devient discret ; au-delà de 0.5, augmentez aussi le débordement des plans. |
Débordement des plans (CSS — inset: -30px de .parallax-layer) |
30 px | Marge cachée qui évite de voir le bord d'un plan quand il glisse. Les montagnes et les sapins, plus larges que la scène (120 %), couvrent déjà les côtés. |
Pied des montagnes et des sapins (CSS — bottom de .parallax-mountains et .parallax-trees, padding-bottom et dégradé du sol) |
6 px et −40 px, sol de 64 px | Remonter les sapins les montre davantage, mais le sol doit rester plus haut que la course verticale des sapins (jusqu'à 37 px dans une scène de 250 px), sinon le ciel apparaît dessous. |
Couleurs (CSS — dégradé de .parallax-scene, border-color des montagnes et des sapins, lune) |
ciel #0a0a2e → #2a1a3e, montagnes #1e1b4b et #2e1065, sapins #064e3b | Les montagnes et les sapins sont des triangles en bordures : changez la couleur de la bordure du bas (border-color: transparent transparent …). |
Hauteur (CSS — height: 250px de .fx-0021-root et de .parallax-scene) |
250 px | Changez les deux ensemble. La course verticale suit la hauteur : dans une scène plus haute, montez aussi le sol. |
Réactivité (CSS — transition: transform 0.1s ease-out) |
0,1 s | 0,4 s donne un décor qui flotte et rattrape le pointeur avec retard. |
FAQ
Comment ajouter un élément au paysage, comme la chouette de la troisième scène ?
Placez-le dans le calque dont il doit suivre la vitesse : dans le calque data-depth="0.6" pour un premier plan, dans 0.25 pour un élément lointain. Donnez-lui position: absolute et une position en bas ou en pourcentage. Pour un plan supplémentaire, ajoutez un .parallax-layer avec son propre data-depth : le script le prend en compte sans modification.
Quelle différence avec Layered Parallax 3D (fx-0007) ?
Mouse Parallax Scene fait glisser des plans à plat, chacun à sa vitesse, sans aucune rotation : c'est un décor qui occupe toute la largeur. Layered Parallax 3D fait pivoter une petite pile de couches en vraie 3D. Pour un bandeau, un fond de section : Mouse Parallax Scene ; pour montrer des épaisseurs empilées : Layered Parallax 3D.
Puis-je mettre plusieurs scènes sur une page ?
Oui. Chaque scène a sa racine .fx-0021-root et le script donne à chacune son instance : chaque scène ne réagit qu'au pointeur qui la survole. C'est le cas sur cette page, où la démo du haut et les trois exemples tournent avec un seul script.