ScrollGratuit

Sticky Image Change

Un bloc « 01 » de 120 px épinglé à 10 px du haut d'une boîte de 280 px, dont le dégradé et l'ombre changent par paliers — indigo, violet, magenta, rose-ambre — sur 920 px de course, pendant que quatre panneaux se révèlent dessous : deux timelines CSS, scroll() et view(), zéro JavaScript.

CSSStickyScroll

Mis à jour le

01

Premiere Section

L'image reste fixe pendant que le contenu defile. Technique ideale pour presenter des fonctionnalites.

Deuxieme Section

Chaque section de texte declenche un changement visuel dans l'image sticky.

Troisieme Section

Les transitions douces guident l'utilisateur a travers le contenu de maniere fluide.

Quatrieme Section

Pattern utilise dans le journalisme interactif et les sites de produits.

Scrollez ↓
Survolez ou cliquez la scène pour interagir

Cet effet est gratuit — la catégorie Scroll en contient 70 au total, dont 12 gratuits. Effect.Labs regroupe 811 effets vanilla. Découvrir la catégorie →

Exemples d'usage

MAISON ORÉE Collection Automne 26 · 60 pièces Filtrer

Indigo

15 pièces
Manteau loden189 €
Pull col roulé95 €
Jupe plissée120 €
Écharpe laine49 €

Prune

15 pièces
Robe midi145 €
Cardigan mohair129 €
Béret39 €
Pantalon large110 €

Terracotta

15 pièces
Trench court210 €
Chemise lin85 €
Sac seau160 €
Foulard45 €

Ivoire

15 pièces
Blazer crème230 €
Maille torsadée115 €
Jean écru99 €
Bonnet35 €

① Bandeau chromatique d'une collection textile — indigo, prune, terracotta, ivoire au fil de 60 pièces

QuandPage catalogue d'une marque de mode : 60 pièces en quatre familles de couleur ; un bandeau sticky sous la barre du site accompagne le défilement et change de teinte en suivant le poids chromatique des produits affichés.
PourquoiUn bandeau de 46 px, pas le fond de la page : il bascule net d'une teinte à la suivante à l'offset où la famille suivante atteint le tiers haut de la boîte, et les 60 pièces gardent leurs propres coloris dessous, sur des cartes blanches — Color Shift (fx-0559) teinterait la section entière derrière les produits, là où l'acheteur compare justement des couleurs ; Scroll Snap Sections (fx-0584, points + sections) figerait la collection en écrans alors que la grille doit défiler librement.
RéglagesBandeau de 46 px (top: 8px) sous une barre de 42 px, boîte de 318 px, quatre familles de quatre pièces sur les 60 ; @keyframes exTextile reprend les pourcentages de ssImgChange avec les dégradés de la collection et anime aussi color (texte brun sur l'ivoire) ; animation-range: -38px 590px cale les paliers sur les familles (course 482 px, bascules mesurées à 103, 260 et 417 px, quand la famille suivante atteint le tiers haut de la boîte) ; libellé « Indigo · pièces 1 à 15 » en quatre span superposés sur la même timeline scroll() ; panneaux en cartes blanches révélés par le view() du code vendu.
PULSE Séance Puissance 12 exercices · 42 min. Le bandeau épinglé en bas suit la zone d'effort de l'exercice à l'écran.
Échauffement Endurance Effort Intensité max
9:41●●● ▲ ▮
Séance PuissanceJeudi · 42 min · 12 exercices

Rameur léger

Échauffement · 5 min

50 %

Mobilité hanches

Échauffement · 2 × 10

—

Squat poids du corps

Échauffement · 2 × 15

—

Fentes marchées

Endurance · 3 × 12

60 %

Pompes

Endurance · 3 × 12

—

Gainage

Endurance · 3 × 45 s

—

Squat barre

Effort · 4 × 8

70 %

Soulevé de terre

Effort · 4 × 6

75 %

Développé couché

Effort · 4 × 8

70 %

Sprints

Intensité max · 6 × 20 s

95 %

Burpees

Intensité max · 3 × 15

90 %

Kettlebell swing

Intensité max · 4 × 15

85 %

② Indicateur de zone d'effort dans une app fitness — le bandeau épinglé en bas passe du bleu au rouge

QuandApplication de sport sur téléphone : une liste d'exercices de puissance croissante ; un bandeau sticky en bas de l'écran passe du bleu (échauffement) au vert, à l'orange (effort) puis au rouge (intensité maximale), avec la zone et la fréquence cardiaque cible.
PourquoiLe bandeau reste collé au bas de l'écran et sa couleur bascule quand le premier exercice de la zone suivante atteint le milieu de la liste : la zone d'effort est lue dans la position du défilement, pas dans un chrono, et remonter le rend au bleu, pendant que chaque ligne se révèle dessous par view() — Split Screen Sticky (fx-0589), bâti sur le même socle, garde un fond fixe et fait tourner l'icône qu'il contient : il ne dit jamais dans quelle zone on est.
RéglagesBloc épinglé en bas — top: auto; bottom: 8px, dernier enfant du contenu (un sticky bas se colle au bord inférieur tant que son parent le dépasse) ; boîte de 212 × 258 px dans un téléphone, douze exercices en quatre zones de trois, bandeau de 40 px ; animation-range: -80px 604px (course 474 px, bascules à 74, 245 et 416 px, quand le premier exercice de la zone suivante atteint le milieu de la liste) ; panneaux révélés sur entry 48px entry 96px, une fois la ligne sortie de sous le bandeau ; barre de défilement masquée.
Rapport de test d'intrusion
Portail client v4.2 · 12 constats, criticité croissante
CVSS 3.1
Informationnel (3)
VULN-01

En-tête Server exposé

2.3
VULN-02

Commentaires HTML de debug en production

2.6
VULN-03

Version de jQuery obsolète

3.7
Moyen (3)
VULN-04

Cookie de session sans SameSite

5.3
VULN-05

Énumération d'utilisateurs au login

5.9
VULN-06

Content-Security-Policy absente

6.5
Élevé (3)
VULN-07

IDOR sur /api/factures/{id}

7.5
VULN-08

XSS stockée dans la page profil

8.2
VULN-09

Jeton de réinitialisation prévisible

8.8
Critique (3)
VULN-10

Injection SQL sur la recherche

9.4
VULN-11

Contournement d'authentification JWT alg=none

9.8
VULN-12

Exécution de code via téléversement de fichier

10.0

③ Signalétique de criticité dans un rapport de sécurité — du vert au rouge en descendant les constats

QuandRapport de test d'intrusion dans un outil de sécurité interne : douze vulnérabilités classées par criticité croissante ; un bandeau sticky passe du vert (informationnel) à l'ambre, à l'orange puis au rouge (critique) à mesure que l'analyste descend.
PourquoiQuatre paliers pour quatre groupes : le bandeau vire à l'ambre, à l'orange puis au rouge à l'instant où l'en-tête du groupe suivant atteint le milieu de la boîte, sans demi-teinte entre deux niveaux — un orange qui glisserait vers le rouge annoncerait une criticité qui n'existe pas. Scroll Progress Beam (fx-0793, rail latéral) mesure la position dans le document ; il ne dit pas la sévérité de ce qui est à l'écran.
RéglagesBandeau de 44 px sous une barre de 40 px, boîte de 320 px, douze constats en quatre groupes de trois avec un en-tête par groupe ; @keyframes exSeverity vert → ambre → orange → rouge, animation-range: -67px 533px (course 452 px, bascules à 68, 218 et 368 px, quand l'en-tête du groupe suivant atteint le milieu de la boîte) ; bordure gauche de chaque constat dans la couleur du groupe, identifiant et score CVSS en chasse fixe ; le libellé « Moyen · CVSS 4,0 – 6,9 » est écrit en toutes lettres, la couleur ne porte jamais seule l'information.

Comment ça marche

Le HTML vendu : le cadre .demo-preview (flex, 280px, overflow: hidden, fond #0a0a0f, sans-serif), la boîte .sdc-scroll-container (100% × 280px, overflow-y: auto, scroll-behavior: smooth, barre de 4 px via ::-webkit-scrollbar), le contenu .ss-imgchange-content (1200px en border-box, padding: 20px 12px), le bloc .ss-imgchange-display et la colonne .ss-imgchange-panels (gap: 16px). Course : 1200 − 280 = 920 px (mesuré). Le bloc de 120px (rayon 14 px, « 01 » en 2rem graisse 800) tient par position: sticky; top: 10px; z-index: 2 : à 20 px du haut au repos, fixé à 10 px dès 10 px de défilement. Sa règle animation: ssImgChange linear; animation-timeline: scroll(nearest) remplace le temps par la position du défileur le plus proche, la boîte. La @keyframes ssImgChange n'a que des plateaux — 0%, 20% indigo → violet (#6366f1 → #8b5cf6), 25%, 45% violet → magenta (→ #d946ef), 50%, 70% magenta → rose (→ #f43f5e), 75%, 100% rose → ambre (→ #f59e0b), chacun avec une ombre 0 8px 30px teintée à 30 %. En pixels : 0-184, 230-414, 460-644, 690-920, séparés par trois transitions de 46 px.

Mesuré dans Chromium, page vierge, les transitions sont asymétriques : l'ombre s'interpole en continu (à 200 px, rgba(113, 99, 243, .3)), mais un linear-gradient ne s'interpole pas entre deux images clés — le moteur saute à la valeur suivante à mi-chemin du segment : 207 → 208 px (22,5 %), 437 → 438 (47,5 %), 666 → 667 (72,5 %). WebKit 26 saute aussi, dès le début de la transition (mesuré 185 px). Une couleur qui change net sous une ombre qui glisse : c'est le caractère de l'effet, une section, une couleur. Le « 01 » ne change jamais — texte statique, aucun compteur ne le pilote.

Les panneaux ont leur propre timeline. Chaque .ss-imgchange-panel (fond blanc à 4 %, bordure à 8 %, h4 de 13,6 px, p de 11,5 px en blanc à 50 %) part de opacity: 0; transform: translateY(20px) et joue sbFadeUp sur animation-timeline: view(), animation-range: entry 0% entry 50% : le fondu commence quand son haut franchit le bord bas de la boîte et s'achève à moitié entré — 36 px de course pour un panneau de 72 px (mesuré à 1 280 px de large) ; both garde l'état final. Au repos : panneau 1 plein, 2 à 0,88, 3 et 4 à 0 ; le 4 atteint 1 à 184 px. Le bloc couvre les 130 px du haut, les panneaux passent dessous : 150 px de lecture. Ils occupent les pixels 160 à 517 du contenu : dès 387 px de défilement, plus aucun n'apparaît, et les 533 derniers pixels de course — troisième et quatrième paliers — défilent sur du vide (à 390 px de large, les textes passent à la ligne et en comblent une partie). scroll-behavior: smooth ne lisse que les défilements programmés (scrollTop = 460 : 332 ms dans Chromium, 528 ms dans Firefox). Le champ JavaScript est vide ; .sdc-scroll-container, l'indice .sdc-scroll-hint (« Scrollez ↓ », absolu dans le cadre, pulsant de 0,3 à 0,7 en 2 s) et sbFadeUp sont le socle commun de la catégorie, identique dans Split Screen Sticky (fx-0589) : coller les deux sur une page ne crée aucun conflit.

Accessibilité

  • prefers-reduced-motion absent du code : mesuré sous émulation, rien ne change — paliers, glissement de 20 px des panneaux, pulsation de l'indice (running), smooth. Les timelines sont pilotées par le lecteur (animation déclenchée par l'interaction, WCAG 2.3.3), la pulsation non. Ajoutez @media (prefers-reduced-motion: reduce) { .ss-imgchange-panel { animation: none; opacity: 1; transform: none } .sdc-scroll-hint { animation: none } .sdc-scroll-container { scroll-behavior: auto } } ; les paliers de couleur ne déplacent rien et peuvent rester.
  • Clavier : mesuré, Tab focalise la boîte sans tabindex dans Chromium et Firefox ; flèche bas avance de 40 px (Chromium) ou 51 px (Firefox), Page suivante de 285 / 303 px, Fin va à 920 — paliers et panneaux suivent, les timelines lisent la position, pas le geste. WebKit ne focalise pas une boîte défilante sans tabindex="0" : ajoutez-le avec un aria-label et un style :focus-visible.
  • Contraste : le « 01 » blanc, 32 px graisse 800 (texte large, seuil 3:1), vaut 4,5:1 sur #6366f1, 4,2:1 sur #8b5cf6, 3,5:1 sur #d946ef, 3,7:1 sur #f43f5e mais 2,2:1 sur l'ambre #f59e0b : le coin bas-droit du dernier palier échoue — passez à #b45309 (5,0:1). Titres des panneaux 18:1 ; paragraphe en blanc à 50 % sur le fond effectif #141419 : 5,3:1 à 11,5 px, juste au-dessus du seuil. L'indice « Scrollez ↓ », blanc à 30 % sur #0a0a0f, vaut 2,6:1 au repos, de 1,2:1 à 1,8:1 sous la pulsation — les deux opacités se multiplient, 0,09 à 0,21 : décoratif, aria-hidden="true".
  • Lecteurs d'écran : le bloc est un div lu « 01 » ; sa couleur n'est pas annoncée — si elle porte un sens (famille, zone, criticité), écrivez-le en toutes lettres, comme le font les trois scènes. Quatre h4 sans h2/h3 au-dessus cassent le plan de la page. Les panneaux à opacity: 0 restent dans l'arbre d'accessibilité et sont tous lus dès le départ, ce qui est voulu. Sans animation-timeline (Firefox), tout est visible à plat. overscroll-behavior: contain évite d'entraîner la page en bout de boîte.

Compatibilité navigateur

CSS seul : animation-timeline: scroll(nearest) et view(), animation-range, position: sticky, dégradés, @keyframes. Champ JavaScript vide, zéro dépendance. Chrome et Edge 115+, Safari et iOS 26+ ; Firefox : aucune version (mesuré : CSS.supports('animation-timeline: scroll()') = false, durée calculée 0s). Ce qu'un visiteur Firefox voit, mesuré page vierge : la boîte défile, le bloc reste épinglé à 10 px, indigo → violet du début à la fin, sans ombre (elle n'existe que dans les images clés), et les quatre panneaux sont visibles, en place, à opacité 1 — l'animation de 0 s en both se fige sur son état final. Rien de caché : le code n'a pas de @supports et n'en a pas besoin. Pour une ombre sous Firefox, posez un box-shadow dans la règle de base du bloc.

Chrome 115+✓ Complet
Firefox✓ Aucune version — à plat : bloc indigo fixe sans ombre, panneaux visibles
Safari 26+✓ Complet (avant 26 : à plat, comme Firefox)
Edge 115+✓ Complet
Mobile iOS 26+✓ Complet (défilement tactile de la boîte)
Android Chrome 115+✓ Complet

Même chose dans Safari avant 26 et Chrome avant 115 : deux animations de 0 s, panneaux à l'état final, bloc sur sa règle de base, page lisible en entier — seule la couleur ne raconte plus rien. Sans position: sticky, le bloc remonterait avec le contenu ; là où overflow n'est pas honoré (clients mail), le contenu s'étire sur 1 200 px, panneaux visibles.

Le code

Copiez les trois blocs dans votre page. Aucune dépendance.

HTML
<div class="sdc-scroll-container">
    <div class="ss-imgchange-content">
      <div class="ss-imgchange-display">01</div>
      <div class="ss-imgchange-panels">
        <div class="ss-imgchange-panel"><h4>Premiere Section</h4><p>L'image reste fixe pendant que le contenu defile. Technique ideale pour presenter des fonctionnalites.</p></div>
        <div class="ss-imgchange-panel"><h4>Deuxieme Section</h4><p>Chaque section de texte declenche un changement visuel dans l'image sticky.</p></div>
        <div class="ss-imgchange-panel"><h4>Troisieme Section</h4><p>Les transitions douces guident l'utilisateur a travers le contenu de maniere fluide.</p></div>
        <div class="ss-imgchange-panel"><h4>Quatrieme Section</h4><p>Pattern utilise dans le journalisme interactif et les sites de produits.</p></div>
      </div>
    </div>
  </div>
  <span class="sdc-scroll-hint">Scrollez ↓</span>
CSS
.ss-imgchange-content {
  height: 1200px;
  padding: 20px 12px;
}

.ss-imgchange-display {
  width: 100%;
  height: 120px;
  border-radius: 14px;
  background: linear-gradient(135deg, #6366f1, #8b5cf6);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  font-weight: 800;
  color: white;
  position: sticky;
  top: 10px;
  z-index: 2;
  animation: ssImgChange linear;
  animation-timeline: scroll(nearest);
}

.ss-imgchange-panels {
  padding-top: 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.ss-imgchange-panel {
  padding: 16px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  opacity: 0;
  transform: translateY(20px);
  animation: sbFadeUp linear both;
  animation-timeline: view();
  animation-range: entry 0% entry 50%;
}

.ss-imgchange-panel h4 {
  font-size: 0.85rem;
  font-weight: 700;
  color: #fff;
  margin: 0 0 6px;
}

.ss-imgchange-panel p {
  font-size: 0.72rem;
  color: rgba(255, 255, 255, 0.5);
  margin: 0;
  line-height: 1.5;
}

.sdc-scroll-container {
  width: 100%;
  height: 280px;
  overflow-y: auto;
  position: relative;
  scroll-behavior: smooth;
}

.sdc-scroll-container::-webkit-scrollbar {
  width: 4px;
}

.sdc-scroll-container::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.05);
}

.sdc-scroll-container::-webkit-scrollbar-thumb {
  background: rgba(139, 92, 246, 0.4);
  border-radius: 2px;
}

.sdc-scroll-hint {
  position: absolute;
  bottom: 8px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 0.65rem;
  color: rgba(255, 255, 255, 0.3);
  z-index: 5;
  pointer-events: none;
  animation: sdcHintPulse 2s ease-in-out infinite;
}

@keyframes sbFadeUp {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes ssImgChange {

  0%,
  20% {
    background: linear-gradient(135deg, #6366f1, #8b5cf6);
    box-shadow: 0 8px 30px rgba(99, 102, 241, 0.3);
  }

  25%,
  45% {
    background: linear-gradient(135deg, #8b5cf6, #d946ef);
    box-shadow: 0 8px 30px rgba(139, 92, 246, 0.3);
  }

  50%,
  70% {
    background: linear-gradient(135deg, #d946ef, #f43f5e);
    box-shadow: 0 8px 30px rgba(217, 70, 239, 0.3);
  }

  75%,
  100% {
    background: linear-gradient(135deg, #f43f5e, #f59e0b);
    box-shadow: 0 8px 30px rgba(244, 63, 94, 0.3);
  }
}

@keyframes sdcHintPulse {

  0%,
  100% {
    opacity: 0.3;
  }

  50% {
    opacity: 0.7;
  }
}
JavaScript (fx-0585)

Personnaliser

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

Option / propriétéDéfautEffet
Paliers de couleur (CSS — @keyframes ssImgChange) 4 plateaux : 0-20 %, 25-45 %, 50-70 %, 75-100 %, dégradés à 135° Chaque paire de pourcentages est un plateau, l'écart de 5 % (46 px) une transition : l'ombre s'y fond, le dégradé bascule à mi-chemin (mesuré 207, 437, 667 px). Cinquième palier : redistribuez les pourcentages (0-16, 20-36…) ; vrai fondu : animez background-color sur une couleur unie.
Course (CSS — .ss-imgchange-content { height: 1200px }, .sdc-scroll-container { height: 280px }) 920 px (230 px par palier) Les pourcentages sont ceux de la course entière, 1 200 − 280. Les panneaux s'arrêtent à 517 px : ramenez le contenu à 800px (course 520) pour que les quatre paliers se jouent pendant qu'il reste à lire, ou ajoutez des panneaux.
Calage des paliers (CSS — animation-range à ajouter sur .ss-imgchange-display) absent (normal : 0 % en haut, 100 % en fin de course) Deux longueurs en pixels redéfinissent où tombent 0 % et 100 % de la timeline : animation-range: -38px 590px place les bascules (22,5 / 47,5 / 72,5 %) aux offsets où chaque groupe prend le relais. Réglage clé des trois scènes ; à recalculer si les hauteurs changent.
Révélation des panneaux (CSS — .ss-imgchange-panel, animation-range: entry 0% entry 50%) fondu sur la première moitié de l'entrée, 20 px de glissement entry 0% entry 100% étale le fondu sur toute l'entrée ; entry 48px entry 96px le retarde de 48 px (sous un bandeau bas). Gardez both : sans lui, un panneau sorti de sa plage retombe à opacity: 0.
Point d'épinglage et hauteur du bloc (CSS — top: 10px, height: 120px) 10 px / 120 px (130 px couverts, 150 px de lecture) Un bloc de 60 px laisse 210 px aux panneaux. top: auto; bottom: 8px l'épingle en bas — il doit alors être le dernier enfant du contenu. Le z-index: 2 le garde au-dessus des panneaux.
Contenu du bloc (HTML — « 01 », CSS — font-size: 2rem; font-weight: 800) « 01 », statique Le texte n'est pas piloté par le défilement : image, SVG ou libellé au choix. Pour un libellé par palier, superposez des span à opacity: 0 sur la même timeline scroll(nearest), chacun avec sa tranche en animation-range — c'est ce que font les scènes.
Défilement doux, indice et barre (CSS — scroll-behavior: smooth, .sdc-scroll-hint, ::-webkit-scrollbar) smooth / « Scrollez ↓ » pulsant 2 s / barre de 4 px smooth n'agit que sur les positions posées par script ou ancre (mesuré : 460 px en 332 ms). L'indice est du français en dur, absolu dans .demo-preview : traduisez-le ou retirez le span avec sa @keyframes sdcHintPulse. La barre stylée n'existe que dans Chromium et Safari ; pour Firefox, scrollbar-width: thin.

FAQ

Pourquoi la couleur saute-t-elle d'un coup alors que l'ombre se fond ?

Parce que les images clés animent un linear-gradient, qu'aucun moteur mesuré n'interpole : Chromium passe à la valeur suivante à mi-chemin du segment (22,5 %, 47,5 %, 72,5 % : 207 → 208, 437 → 438, 666 → 667 px), WebKit 26 dès son début (185 px). L'ombre — une couleur, des longueurs — s'interpole normalement sur les 46 px de chaque transition (à 200 px, rgba(113, 99, 243, .3)). Cette bascule nette est le caractère de l'effet : une section, une couleur. Pour un fondu continu, animez background-color sur une couleur unie, ou une variable enregistrée par @property que le dégradé lit.

Qu'est-ce qui le distingue de Split Screen Sticky (fx-0589) ?

Le socle est identique — même boîte .sdc-scroll-container de 280 px, même bloc collé à top: 10px, mêmes panneaux révélés par sbFadeUp sur view() entre entry et entry 50% — mais ce qui est animé au défilement diffère. Dans fx-0589 (premium), le bloc de 100 px garde un fond fixe (#1a1a3e → #2d1b69) et c'est l'icône SVG qu'il contient qui tourne de 360° sur animation-timeline: scroll(), en continu, sur 720 px de course, devant trois cartes à liste. Dans fx-0585, c'est le bloc lui-même qui change : dégradé et ombre par paliers, quatre couleurs pour quatre panneaux, 920 px de course, rien d'animé à l'intérieur. Prenez fx-0585 quand la couleur doit dire où l'on est (famille, zone, criticité) ; fx-0589 quand un visuel fixe doit vivre pendant que le texte défile.

Comment faire coïncider un palier avec chaque panneau, ou chaque groupe de panneaux ?

Par animation-range en pixels sur le bloc, sans toucher aux pourcentages. Relevez l'offset auquel chaque groupe doit prendre le relais (son haut dans le contenu, moins la hauteur où vous voulez qu'il passe : bord bas du bloc, milieu de la boîte) ; ces offsets doivent tomber sur les bascules, à 22,5 %, 47,5 % et 72,5 % de la plage. Pour des relais réguliers, à partir des deux premiers offsets o₁ et o₂ : longueur = (o₂ − o₁) ÷ 0,25, début = o₁ − 0,225 × longueur — un début négatif est permis, le premier palier est simplement déjà entamé au repos. Les trois scènes tiennent ainsi en une ligne (-67px 533px pour douze constats en quatre groupes, course 452 px). Si les groupes ont des hauteurs très différentes, changez plutôt les pourcentages de la @keyframes. Dans le code vendu, rien n'est calé : les paliers se répartissent sur la course entière et les panneaux s'arrêtent à 517 px sur 920.