Scroll✨ Premium

Parallax Layers

Une scène de nuit dessinée en CSS (étoiles, lune, crêtes en triangles de bordure, brume, sol) épinglée par position: sticky dans un défileur de 280 px : sur une course de 1 400 px, cinq plans glissent sur la timeline nommée --parallaxScroll, de 40 px d'amplitude pour les étoiles à 160 px pour la brume. Zéro JavaScript ; Firefox voit la scène à plat.

CSSscroll()Parallax

Mis à jour le

Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Scroll comprend 70 effets, dont 12 gratuits. Découvrir la catégorie →

3 exemples d'usage

Écran d'attente d'un planétarium — borne d'accueil du hall — Parallax Layers exemple 1

① Écran d'attente d'un planétarium — borne d'accueil du hall

QuandBorne du hall : le ciel nocturne, la lune et la ligne de crête restent dans le cadre pendant que le visiteur fait défiler ; les plans se décalent, le programme des séances est indiqué par-dessus.
PourquoiCinq cartes de séances et un ou deux gestes du doigt pour les parcourir : le viewport épinglé garde le ciel, la lune et les crêtes dans le cadre du premier au dernier pixel de course (mesuré), et les plans glissent à des vitesses différentes sous les cartes qui passent — l'image reste, c'est le programme qui bouge. fx-0592 fait défiler ses calques avec leur section : dès les premières cartes, la scène monterait et sortirait du cadre, laissant le programme sur un fond nu.
RéglagesDéfileur à la hauteur du cadre (360 px, viewport épinglé à 360 px), piste en height: auto : le programme suit le viewport dans le flux, remonté de 360 px (margin-top: -360px) pour défiler par-dessus la scène. Course mesurée 392 px, sur laquelle s'étalent les amplitudes fixes. Ciel #070a1c, lune à 54 px sous la barre, cartes de séances en rgba(10,14,40,.74), barre de défilement masquée, tabindex="0" sur le défileur, aria-hidden sur le viewport. Le défilement automatique est un artifice de démonstration.
Page de réservation d'un refuge de montagne — nuitées en altitude — Parallax Layers exemple 2

② Page de réservation d'un refuge de montagne — nuitées en altitude

QuandPage « Réserver » du refuge : la scène nocturne (étoiles, lune, deux sommets, brume de vallée) reste en fond pendant que les dates et le tarif de la nuitée sont choisis dans le cadre.
PourquoiLes triangles de montagne, la brume et les étoiles sont déjà dessinés en CSS (::before/::after, radial-gradient) : le refuge n'a aucune photo de nuit à fournir — les autres parallaxes du lot n'ont que des formes abstraites à remplacer.
RéglagesMême montage, course mesurée 326 px, palette du refuge : crêtes en bleu ardoise (rgba(100,130,170,.32) et rgba(120,150,190,.28)), brume grise, sol rgba(11,18,32,.97), lune chaude #fff7db → #e2d3a3 à 58 px du haut ; barre de défilement fine conservée (c'est une page web), formulaire et tarifs en cartes opaques à 86 %.
Illustration d'un conte du soir — application de lecture pour enfants sur tablette — Parallax Layers exemple 3

③ Illustration d'un conte du soir — application de lecture pour enfants sur tablette

QuandPage d'un conte : le texte défile, la nuit reste épinglée derrière, la lune et les crêtes se décalent doucement à chaque geste de l'enfant.
PourquoiAmplitudes faibles (20 à 120 px sur une course de 600 %) : le mouvement est lent et réversible, l'enfant peut remonter sans que la scène saute — un défilement à vitesse fixe comme fx-0578 Sticky Horizontal (publié, animation temporelle) ne suivrait pas sa main.
RéglagesCourse mesurée 274 px, défilement de démonstration ralenti à 150 px/s ; ciel prune #160f2a, crêtes et brume violet et rose (rgba(168,85,247,.28), rgba(244,114,182,.26)), lune de 46 px (top: 56px; right: 28px) jaune pâle au halo de 30 px, étoiles de 3 px (deux de 4 px) ; texte du conte en Georgia 16,5 px sur ombre portée, sans carte, pour laisser la scène visible entre les lignes.

Comment ça marche

Le HTML vendu emboîte trois cadres et cinq plans. Le cadre .demo-preview (flex centré, min-height: 300px, position: relative, fond #0a0a0f) contient le défileur .parallax-container (100% × 280 px, overflow: hidden auto, scroll-timeline: --parallaxScroll y), qui contient la piste .parallax-scene (height: 600%, soit 1 680 px), qui contient le viewport .parallax-viewport (position: sticky; top: 0, 280 px, overflow: hidden). La course vaut 1 680 − 280 = 1 400 px et le viewport, collé au haut du défileur, ne quitte jamais le cadre (mesuré : bord haut constant du premier au dernier pixel). Dedans, cinq plans en position: absolute : .parallax-stars (100 % du viewport, huit .p-star blanches de 2 px — deux de 3 px — entre 5 et 30 % du haut, opacités .3 à .8), .parallax-moon (30 px, top: 20px; right: 30px, dégradé radial #e0e7ff → #a5b4fc, halo de 20 px), puis trois bandes ancrées en bas par .slr-parallax-layer (bottom: 0) : .slr-parallax-bg (180 px de dégradé indigo, dont les deux crêtes sont des triangles de bordure de 280 × 140 px à left: -10% et 240 × 110 px à right: -5%), .parallax-mid (120 px, dont le ::before de 80 px porte deux dégradés radiaux violet et indigo : la brume) et .parallax-fg (60 px, rgba(15,15,26,.95) vers transparent : le sol). Sous le défileur, l'indice .slr-scroll-hint « Scrollez pour le parallax » (11,2 px, blanc à 40 %, bottom: 8px du cadre) rebondit de 4 px toutes les 2 s. Le champ JavaScript est vide.

Le moteur tient en deux propriétés. scroll-timeline: --parallaxScroll y sur le défileur déclare une timeline nommée qui suit sa position verticale ; chaque plan y attache son animation par animation-timeline: --parallaxScroll, avec animation-duration: auto, animation-timing-function: linear, animation-fill-mode: both et animation-range: normal : la progression vaut scrollTop ÷ 1400. Quatre @keyframes, tous en translateY : parallaxStars 20 → −20 px (étoiles et lune), parallaxSlow 40 → −40 px (crêtes), parallaxMed 80 → −80 px (brume), parallaxFast 120 → −30 px (sol). Plus le plan est proche, plus il court : 40, 80, 160 et 150 px sur la même course, soit 1 px pour 35 px défilés au fond et 1 px pour 8,75 à la brume. Mesuré dans Chromium 151 et WebKit 26.5, page vierge, valeurs identiques : à 140 px de défilement (10 %), 16 / 32 / 64 / 105 px ; à 700 px (50 %), 0 / 0 / 0 / 45 ; à 1 400 px, −20 / −40 / −80 / −30. Deux copies collées dans la même page donnent deux défileurs et deux timelines indépendantes (mesuré : chacune poussée à 700 px, chacune à 0) — pas d'id, rien à renommer.

Au repos, la scène est enfoncée : les bases des crêtes sont 40 px sous le bord bas, la brume et le sol sont entièrement hors cadre, la lune est à 40 px du haut. En défilant, tout remonte à des vitesses différentes ; à mi-course les crêtes touchent le bord et le sol montre ses 15 premiers pixels ; en fin de course les crêtes flottent 40 px au-dessus du bord, le sol occupe la bande 208–268 px du viewport et laisse sous lui 30 px de fond de cadre (sa dernière image-clé est −30, pas 0), la lune touche le bord haut. Le viewport est transparent : le ciel est le fond de .demo-preview. Deux règles tiennent l'ensemble. La hauteur fixe du défileur : en height: 100% sous un parent sans hauteur définie, il retombe à la hauteur de son contenu, la course vaut 0 et rien ne bouge (mesuré dans les trois moteurs). Et l'overflow: hidden du viewport, qui coupe les crêtes débordantes et le sol enfoncé de 120 px au repos — sans lui, le viewport gagnerait sa propre barre de défilement.

Accessibilité

  • prefers-reduced-motion absent du code : mesuré sous émulation, les plans suivent toujours le défilement (0 / 0 / 0 / 45 px à mi-course, comme sans préférence) et l'indice rebondit toujours. Rien n'est caché pour autant : le parallaxe n'avance que par le geste du lecteur, seul le rebond tourne en boucle. Ajoutez @media (prefers-reduced-motion: reduce) { .slr-scroll-hint { animation: none } } ; pour figer aussi les plans, reprenez dans cette media query la liste de sélecteurs du repli @supports : la scène reste à plat, complète.
  • Clavier : mesuré, Tab donne le focus au défileur sans tabindex dans Chromium 151 et Firefox 153 (activeElement = .parallax-container) : flèche bas avance de 40 px (51 dans Firefox), Page suivante de 285 (303), Fin va au bout, 1 400. WebKit 26.5 ne focalise pas la zone : le focus reste sur body, les flèches ne font rien. Ajoutez tabindex="0", un aria-label et un style :focus-visible. Au doigt, le geste doit commencer dans la zone ; overscroll-behavior: contain évite d'entraîner la page en bout de course.
  • Contraste : le seul texte est l'indice, 11,2 px en blanc à 40 % sur #0a0a0f — rendu rgb(108,108,111), 3,8:1, sous le seuil de 4,5:1 des petits corps ; il est écrit en français en dur. Passez-le à 60 % (rgba(255,255,255,.6)), traduisez-le ou retirez le span — la @keyframes hintBounce part avec lui. Tout texte posé sur la scène doit tenir son contraste sur le ciel et sur les crêtes, plus claires.
  • Lecteurs d'écran et repli : quinze div et span vides plus une phrase française — rien à lire. Posez aria-hidden="true" sur .parallax-viewport (ou role="img" et un aria-label sur le défileur si la scène illustre quelque chose) et gardez le contenu utile hors de la scène : un lecteur d'écran ne défile pas pour faire apparaître un sol. Sans animations pilotées par le défilement, le repli @supports montre la scène complète et immobile ; sans CSS du tout, il ne reste que l'indice.

Compatibilité navigateur

CSS seul : scroll-timeline (timeline nommée), animation-timeline, animation-range, animation-duration: auto, position: sticky, overflow: hidden auto, dégradés, triangles de bordure, cinq @keyframes. Zéro dépendance, zéro JavaScript. Les animations pilotées par le défilement existent dans Chrome et Edge 115+, Safari et iOS 26+ (mesuré dans WebKit 26.5 : mêmes valeurs que Chromium 151 à chaque position). Firefox : aucune version. Mesuré dans Firefox 153 : CSS.supports('animation-timeline: scroll()') répond faux et animation-duration: auto est calculée 0s. Le repli @supports not (animation-timeline: scroll()) du code vendu met animation: none sur les cinq plans : chacun reste à sa place de repos (transform: none mesuré à 0, 350, 700, 1 050 et 1 400 px de défilement) — étoiles et lune en haut, crêtes et brume posées sur le bord bas, sol collé au bord. Le défileur défile normalement sur 1 400 px, le viewport reste épinglé, l'indice rebondit : un visiteur Firefox voit une scène de nuit fixe et complète, que le défilement ne fait pas bouger. Sans ce repli, il verrait les images-clés finales : plans remontés de 20 à 80 px et bande vide de 30 px sous le sol (mesuré).

Chrome 115+✓ Complet
Firefox✓ Aucune version : scène fixe à plat (repli @supports), défilement sans parallaxe
Safari 26+✓ Complet (mesuré dans WebKit 26.5)
Edge 115+✓ Complet
Mobile iOS 26+✓ Complet (défilement tactile de la zone)
Android Chrome 115+✓ Complet

Le repli ne cache rien : il annule les cinq animations et la scène s'affiche à plat, complète — la composition de mi-course, sol compris. Si le mouvement est le message, masquez l'invitation dans le même bloc : .slr-scroll-hint { display: none }. Pour un parallaxe réel partout, il faut un écouteur scroll qui écrit les transform, comme le fait Parallax Layers (fx-0576).

Le code

Structure HTML à coller dans votre page (le CSS + JS sont inclus avec Premium) :

index.html — structure
<div class="demo-preview">
  <div class="parallax-container">
    <div class="parallax-scene">
      <div class="parallax-viewport">
        <div class="parallax-stars slr-parallax-layer">
          <span class="p-star"></span><span class="p-star"></span><span class="p-star"></span><span class="p-star"></span>
          <span class="p-star"></span><span class="p-star"></span><span class="p-star"></span><span class="p-star"></span>
        </div>
        <div class="parallax-moon"></div>
        <div class="slr-parallax-bg slr-parallax-layer"></div>
        <div class="parallax-mid slr-parallax-layer"></div>
        <div class="parallax-fg slr-parallax-layer"></div>
      </div>
    </div>
  </div>
  <span class="slr-scroll-hint">…</span>
</div>
Débloquer le code complet — 9,90 € HT/mois

Le code complet HTML + CSS + JS de Parallax Layers, prêt à coller — et les 811 effets. Ou 299 € une fois, accès à vie.

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
Amplitudes des plans (CSS — @keyframes parallaxStars / parallaxSlow / parallaxMed / parallaxFast) 20 → −20, 40 → −40, 80 → −80, 120 → −30 px Des pixels fixes quelle que soit la course : sur 1 400 px, 40 px valent 1 px pour 35 défilés ; sur 400 px, 1 pour 10. Gardez le plan le plus proche le plus rapide, c'est ce qui fait la profondeur. Terminez parallaxFast à translateY(0) pour que le sol reste collé au bord en fin de course.
Course (CSS — .parallax-scene { height: 600% }) 1 680 px de piste, 1 400 px de course Course = hauteur de la piste − hauteur du défileur ; les amplitudes s'y étalent. 300% donne 560 px et un parallaxe 2,5 fois plus vif ; height: auto avec du contenu placé après le viewport (remonté d'une marge négative égale à sa hauteur) fait défiler ce contenu par-dessus la scène, comme dans les trois scènes ci-dessus.
Hauteur du cadre (CSS — .parallax-container et .parallax-viewport { height: 280px }) 280 px, les deux Changez les deux ensemble : le viewport épinglé doit faire la hauteur du défileur. Une valeur fixe est obligatoire sur le défileur (en height: 100% sous un parent sans hauteur : course 0, mesuré). Plans ancrés en bas et étoiles en pourcentage : la scène se redistribue seule.
Ciel et couleurs des plans (CSS — .demo-preview { background }, .slr-parallax-bg, .parallax-mid::before, .parallax-fg) ciel #0a0a0f, indigo rgba(99,102,241,.15–.25), violet rgba(139,92,246,.2–.3), sol rgba(15,15,26,.95) Le viewport est transparent : le ciel est le fond du cadre. Les plans sont des dégradés translucides : sur un ciel clair, montez leurs opacités (.4 à .6) ou passez à des couleurs pleines. Le sol, opaque à 95 %, sert aussi de fond à ce que vous posez en bas du cadre.
Crêtes (CSS — .slr-parallax-bg::before et ::after) 280 × 140 px à left: −10 % ; 240 × 110 px à right: −5 % Des triangles de bordure : la largeur vaut border-left + border-right, la hauteur border-bottom. 200 px de bordures font une crête de 400 × 200 px ; left: 30% la déplace. Une troisième crête demande un élément de plus dans la bande.
Étoiles et lune (HTML — huit .p-star ; CSS — .p-star:nth-child(n), .parallax-moon) 8 points de 2 px (deux de 3 px), opacités .3 à .8 ; lune 30 px à top 20 / right 30, halo 20 px Ajoutez des span et leur règle :nth-child (position en %, opacité) ; sans règle, un point tombe en haut à gauche. La lune partage parallaxStars avec les étoiles ; donnez-lui parallaxSlow pour la rapprocher, ou aucune animation pour la fixer.
Indice « Scrollez pour le parallax » (HTML + CSS — .slr-scroll-hint, @keyframes hintBounce) 8 px du bas du cadre, 11,2 px, blanc à 40 %, rebond 4 px / 2 s Ancré sur .demo-preview (position: relative) : sans ce cadre, il tombe au bas de la page. Texte français en dur, 3,8:1 de contraste : traduisez, éclaircissez ou supprimez le span. C'est le seul mouvement autonome de l'effet.
Repli sans animation-timeline (CSS — @supports not (animation-timeline: scroll())) animation: none sur les cinq plans Firefox et les navigateurs anciens voient la scène à plat. Pour leur montrer autre chose, remplacez le bloc : un transform: translateY(…) fixe par plan compose la vue de votre choix.

FAQ

Trois causes, mesurées. Le navigateur : Firefox n'exécute aucune animation pilotée par le défilement, quelle que soit sa version — le repli montre la scène à plat et c'est normal ; Chrome avant 115 et Safari avant 26 sont dans le même cas. La hauteur : le défileur doit avoir une hauteur fixe (280 px vendus) ; en height: 100% sous un parent sans hauteur définie, il retombe à la hauteur de son contenu, la course vaut 0 et la timeline n'a rien à suivre. Le défileur lui-même : la timeline est nommée sur .parallax-container, c'est lui qu'il faut faire défiler, pas la page ; la molette ne l'atteint que si le pointeur est dessus, et un overflow: visible posé par votre CSS le rend inerte. Pour piloter la scène par le défilement de la page, remplacez la timeline nommée par animation-timeline: scroll(root) sur les cinq plans, retirez l'overflow du conteneur et gardez le viewport sticky dans une section assez haute.
Parce que parallaxFast va de 120 à −30 px sur une bande de 60 px ancrée en bas. Au repos, la bande est 120 px sous le bord : invisible. Elle affleure à 700 px de course (15 px visibles), est entière à 1 050 px, puis monte jusqu'à −30 : ses 60 px occupent la bande 208–268 d'un viewport de 280 et les 30 px du bas montrent le fond du cadre — mesuré identique à 390 et 1 280 px de large. C'est le dessin vendu : les plans s'enfoncent puis s'élèvent, et la composition « assemblée » est celle de mi-course, la même que le repli Firefox. Pour un sol collé au bord jusqu'au bout, terminez parallaxFast à translateY(0) ; pour cacher l'écart sans toucher aux amplitudes, donnez au sol 90 px de haut (.parallax-fg { height: 90px }) : à −30 il couvre encore le bord.
Le moteur et la scène. fx-0576 est du JavaScript : un écouteur scroll et six écritures de style par événement sur des formes abstraites (halo, trois formes tournées de 180°, mot PARALLAXE grossi et fondu), avec quatre const globales qui limitent la page à une instance ; en échange, il tourne dans Firefox. fx-0573 n'a pas une ligne de script : une timeline nommée, quatre @keyframes, un viewport sticky qui ne sort jamais du cadre, autant d'instances que voulu (mesuré : deux copies, deux timelines indépendantes) — et rien ne bouge dans Firefox. Sa scène est un paysage dessiné en CSS, pas des formes à remplacer. fx-0592, comme Parallax Layers CSS (fx-0548), est aussi en CSS pur mais avec animation-timeline: scroll() anonyme et des calques qui défilent avec leur section : la scène monte et sort du cadre. fx-0573 est le seul des trois où le cadre reste épinglé pendant que les plans glissent dedans.