Scroll✨ Premium

Mixed Content Snap

Une fenêtre de 280 px en scroll-snap-type: y — proximité, pas mandatory — et cinq sections de 280, 140, 140, 80 et 280 px alignées en start : points d'accroche à 0, 280, 420, 560 et 640 px, une section plus courte que la fenêtre ne l'occupe jamais seule, et un cran de molette depuis le haut s'arrête à 100 px, entre deux. Zéro JavaScript.

CSSMixedSnap

Vous aurez accès à la démo interactive avec un compte gratuit.

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

Bulletin météo structuré en mobile — l'alerte courte, l'heure par heure pleine, les 7 jours à demi — Mixed Content Snap exemple 1

① Bulletin météo structuré en mobile — l'alerte courte, l'heure par heure pleine, les 7 jours à demi

QuandÉcran d'une application météo : une alerte (section courte, urgente), les prévisions heure par heure (section pleine), puis les prévisions à 7 jours (demi-section) — la hauteur reflète le poids informationnel.
PourquoiLa section d'alerte doit accrocher plus vite sur un espace réduit : à 72 px, elle est lue puis quittée d'un geste, et l'heure par heure prend l'écran entier. Vertical Snap (fx-0593), sections identiques, nivelle la hiérarchie et donne autant d'espace à l'alerte critique qu'à l'information secondaire.
RéglagesFenêtre .sn-mixed-container à 296 px (l'écran du téléphone) ; alerte .sn-quarter à 72 px, heure par heure .sn-full à 296 px, 7 jours .sn-half à 148 px avec scroll-snap-align: end pour que le dernier arrêt (220 px) soit atteignable ; fonds portés par les classes, proximité conservée, indice « Défiler ↓ » gardé dans l'écran.
Bilan de séance de rééducation kiné — titre et score au quart, graphique ROM en plein, recommandations à demi — Mixed Content Snap exemple 2

② Bilan de séance de rééducation kiné — titre et score au quart, graphique ROM en plein, recommandations à demi

QuandUn thérapeute consulte sur tablette un bilan de séance : titre et score global (section quart), graphique d'amplitude articulaire (section pleine), recommandations patient (demi-section) — le rythme de lecture suit la densité informative.
PourquoiLa hauteur de section code la densité du contenu : le score se lit en un coup d'œil, le graphique demande l'écran entier. Snap + Progress (fx-0597) nivelle toutes les sections à la même hauteur et perd la hiérarchie clinique du bilan — et son script d'index suppose des sections égales.
RéglagesFenêtre à 272 px ; en-tête + score .sn-quarter à 68 px, graphique .sn-full à 272 px, recommandations .sn-half à 136 px en end ; scroll-snap-type: y mandatory (un bilan ne s'arrête jamais entre deux blocs) ; scroll-behavior: auto sous prefers-reduced-motion.
Newsletter interactive à poids éditoriaux distincts — manchette au quart, article en plein, deux brèves à demi — Mixed Content Snap exemple 3

③ Newsletter interactive à poids éditoriaux distincts — manchette au quart, article en plein, deux brèves à demi

QuandUn magazine en ligne envoie une newsletter riche en HTML : manchette (section quart), article principal (section pleine), deux brèves (demi-sections) — l'accroche reflète l'importance éditoriale.
PourquoiLe poids visuel des sections communique l'importance éditoriale : la taille parle avant le texte. Scroll Snap Sections (fx-0584), sections identiques avec points de navigation, ne peut pas différencier un article de 500 mots d'un titre de trois mots.
RéglagesFenêtre à 280 px comme le code ; manchette .sn-quarter à 70 px, article .sn-full à 280 px, deux brèves .sn-half à 140 px — l'arrêt final (350 px) montre les deux brèves ensemble ; proximité conservée, le lecteur peut s'arrêter au milieu de l'article ; fonds clairs propres à la lettre.

Comment ça marche

Le HTML vendu est un .demo-preview (flex centré, min-height: 300px, position: relative, fond #0a0a0f) qui contient .sn-mixed-containerwidth: 100%, height: 280px, overflow-y: auto, scroll-snap-type: y, scroll-behavior: smooth — et, à côté, l'indice .sdc-scroll-hint « Scrollez ↓ » : absolu à 8 px du bas du .demo-preview, 10,4 px, blanc à 30 %, opacité pulsée de .3 à .7 en 2 s (sdcHintPulse). Dans le conteneur, cinq .sn-mixed-section en scroll-snap-align: start, colonne flex centrée, padding: 16px, dont la hauteur vient d'une seconde classe : .sn-full 280 px (la fenêtre exactement), .sn-half 140 px, .sn-quarter 80 px. L'ordre vendu — pleine, demi, demi, quart, pleine — fait 920 px de contenu pour 640 px de course. Les fonds sont cinq dégradés à 135° attribués par :nth-child(1) à (5), de #1e1b4b à #8b5cf6 : ils suivent le rang, pas la taille. Textes : h4 .85 rem (13,6 px) blanc, p .68 rem (10,9 px) blanc à 60 % ; chaque h4 porte en ligne font-family: Inter, …, un reste du catalogue.

Les points d'accroche sont les hauts de section : 0, 280, 420, 560 et 640 px — le dernier coïncide avec la fin de course parce que la section finale fait la hauteur de la fenêtre. C'est là que les hauteurs mixtes changent la lecture : une section plus courte que la fenêtre ne la remplit jamais seule. À 280, les deux demi-sections se partagent l'écran ; à 420, la seconde demi, le quart et 60 px de la finale ; à 560, le quart occupe le haut et la finale les 200 px restants. Le rythme, ce sont les écarts entre arrêts : 280, 140, 140, 80. Et scroll-snap-type: y sans second mot-clé vaut proximity, pas mandatory : l'accroche ne joue qu'à portée d'un point. Mesuré dans Chromium 151 : une position laissée à 93 px d'un point y est ramenée, à 94 px elle reste — le seuil est un tiers de la fenêtre (280 / 3). Conséquence : un cran de molette (100 px) depuis le haut s'arrête à 100 px et y reste (encore à 100 px deux secondes plus tard) ; deux crans en 120 ms atteignent 280 ; ensuite chaque cran retombe à portée d'un point : 280 → 420 → 560 → 640. Au trackpad, 5 × 20 px sont ramenés à 0, 13 × 20 px s'arrêtent à 143 px, entre deux.

scroll-behavior: smooth ne concerne que les défilements programmés (scrollTo, ancres, touches) : mesuré 0 → 640 px en 395 ms, 226 px parcourus à 100 ms. Aucun JavaScript : pas d'écouteur, rien à retirer, l'animation d'accroche est celle du navigateur. Trois limites tiennent au code lui-même. Les fonds par :nth-child : une sixième section n'en a aucun (mesuré background: none). La dernière section : passée en .sn-half, son haut (640) dépasse la course (500) et elle ne s'aligne jamais en haut (mesuré : arrêt à 500). L'indice : il chevauche les 10 derniers pixels du conteneur (280–292 px contre 10–290) et, sans le .demo-preview positionné, file au bas de la fenêtre (mesuré à 479 px pour un conteneur fini à 280). Aucune variable CSS du site, aucune erreur console.

Accessibilité

  • prefers-reduced-motion absent : sous reduce, scroll-behavior: smooth reste actif (mesuré : 23 px parcourus 50 ms après un scrollTo) et la pulsation de l'indice tourne (playState: running). Le défilement est à l'initiative du lecteur et l'animation d'accroche est celle du navigateur, mais ajoutez @media (prefers-reduced-motion: reduce) { .sn-mixed-container { scroll-behavior: auto } .sdc-scroll-hint { animation: none } }. Point positif du mode proximité : aucun contenu n'est inatteignable, contrairement à mandatory qui peut retenir le lecteur entre deux points.
  • Clavier : le conteneur est un div sans tabindex. Les Chromium récents et Firefox rendent les zones défilantes sans enfant focalisable atteignables au clavier (mesuré dans Chromium 151 : Tab s'y arrête, flèche bas 40 px par appui sans accroche — 40, 80, 120, 160 —, PageDown 420, Espace 280, End 640), Safari non. Posez tabindex="0", role="region" et un aria-label sur .sn-mixed-container.
  • Contraste mesuré sur les pixels des captures : h4 blanc de 14,0:1 (section 1) à 5,1:1 (section 5) — conforme ; p blanc à 60 % : 6,0 · 5,1 · 4,2 · 3,3 · 2,8:1 — les sections 3 à 5 sont sous 4,5:1, et à 10,9 px le texte n'est pas « large ». Passez rgba(255, 255, 255, .6) à .85 (≥ 4,5:1 partout) ou éclaircissez moins les derniers dégradés. L'indice (10,4 px, 30 % de blanc) mesure 2,6:1 sur #0a0a0f et 2,5:1 sur la section qu'il recouvre : décoratif, mettez-le aria-hidden="true" — et traduisez « Scrollez ↓ », codé en dur.
  • Tailles et structure : 13,6 px pour les titres, 10,9 px pour les paragraphes — ce sont les tailles d'une carte de catalogue, remontez-les à 14–16 px en page. Les titres sont des h4 sans h1h3 au-dessus : adaptez le niveau à votre plan. Les sections sont des div : pour un lecteur d'écran, le rythme des hauteurs n'existe pas, la hiérarchie doit aussi être dans les titres. Au doigt, l'accroche de proximité fonctionne et le conteneur de 280 px laisse le geste continuer sur la page en fin de course (overscroll-behavior par défaut) : pas de piège au défilement.

Compatibilité navigateur

CSS seul : scroll-snap-type / scroll-snap-align (syntaxe moderne), overflow-y: auto, linear-gradient, @keyframes ; scroll-behavior: smooth en confort. Aucun script, aucune bibliothèque, aucune variable CSS. C'est du CSS classique, pas une animation pilotée par animation-timeline : Firefox le rend complètement, alors qu'il ne prend en charge les animations au défilement natives dans aucune version.

Chrome 69+✓ Complet
Firefox 68+✓ Complet
Safari 11+✓ Complet (lissage à partir de 15.4)
Edge 79+✓ Complet
Mobile iOS 11+✓ Complet (accroche au doigt)
Android Chrome✓ Complet (accroche au doigt)

Sans scroll-snap (navigateurs antérieurs), le conteneur est une simple boîte défilante : les cinq sections gardent leurs hauteurs et leurs fonds, tout reste lisible, rien n'accroche. Sans scroll-behavior (Safari avant 15.4), les sauts programmés sont instantanés ; le défilement au doigt ou à la molette n'en dépend pas. Sans JavaScript : identique, il n'y en a pas.

Le code

Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :

index.html — structure
<div class="demo-preview">
  <div class="sn-mixed-container">
    <div class="sn-mixed-section sn-full">
      <h4>Section Principale</h4>
      <p>Hauteur complete</p>
    </div>
    <div class="sn-mixed-section sn-half">
      <h4>Section Moyenne</h4>
      <p>Demi-hauteur</p>
    </div>
    <div class="sn-mixed-section sn-half">
      <h4>Section Moyenne</h4>
      <p>Demi-hauteur</p>
    </div>
    <div class="sn-mixed-section sn-quarter">
      <h4>Petite</h4>
      <p>Compacte</p>
    </div>
    <div class="sn-mixed-section sn-full">
      <h4>Section Finale</h4>
      <p>Retour hauteur complete</p>
    </div>
  </div>
  <span class="sdc-scroll-hint">Scrollez ↓</span>
</div>
🔒 Débloquer le code complet — à partir de 2,99 € le 1er mois

HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.

Personnaliser

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

Option / propriétéDéfautEffet
Mode d'accroche (CSS — .sn-mixed-container scroll-snap-type) y (= y proximity) En proximité, l'accroche ne joue qu'à moins d'un tiers de fenêtre d'un point (93 px) : un cran de molette depuis le haut reste à 100 px. y mandatory ramène toujours au point le plus proche — sans risque ici, aucune section ne dépasse la fenêtre.
Hauteur de la fenêtre (CSS — .sn-mixed-container et .sn-full) 280 px / 280 px Les deux vont ensemble : une pleine section doit faire exactement la fenêtre pour l'occuper seule, et le seuil de proximité suit (un tiers). En page, 100vh pour les deux ; dans un composant, une valeur fixe.
Paliers (CSS — .sn-half, .sn-quarter) 140 px / 80 px Ce sont les écarts entre arrêts. Ajoutez des classes (.sn-third à 93 px). Un écart inférieur au seuil enchaîne deux arrêts en un cran ; un écart de 280 laisse une zone morte de 94 à 186 px où un cran s'arrête entre deux.
Alignement (CSS — .sn-mixed-section scroll-snap-align) start center centre une section courte dans la fenêtre, ses voisines de part et d'autre ; end sur la dernière section la rend atteignable même plus courte que la fenêtre (son bas s'aligne sur le bas du cadre).
Ordre et dernière section (HTML) pleine · demi · demi · quart · pleine Le dernier point d'accroche doit rester ≤ la course (contenu − 280). Terminez par une .sn-full, ou donnez à la dernière section scroll-snap-align: end, ou ajoutez un padding-bottom au conteneur.
Fonds (CSS — .sn-mixed-section:nth-child(n)) 5 dégradés #1e1b4b → #8b5cf6, par rang Liés à la position, pas à la classe de taille : la sixième section n'a pas de fond. Portez-les sur .sn-full / .sn-half / .sn-quarter pour que la couleur dise la hauteur.
Lissage (CSS — scroll-behavior) smooth Anime scrollTo, les ancres et les touches (395 ms pour 640 px mesurés), pas la molette ni le doigt. Passez à auto sous prefers-reduced-motion.
Indice (HTML/CSS — .sdc-scroll-hint) « Scrollez ↓ », 8 px du bas, pulsation 2 s Exige un parent en position: relative et chevauche 10 px du conteneur. Remontez-le (bottom: 18px), traduisez-le, ou supprimez-le avec sa @keyframes.

FAQ

Parce que scroll-snap-type: y sans second mot-clé signifie proximity : le navigateur n'accroche que si le défilement s'arrête à portée d'un point — dans Chromium, un tiers de la fenêtre, soit 93 px ici (mesuré : 93 px ramenés, 94 px laissés). Un cran de molette fait 100 px : depuis le haut, il s'arrête à 100 px, à 100 px du point 0 et à 180 px du point 280, hors de portée des deux. Le second cran atteint 200 px, à 80 px du point 280, et l'accroche joue ; ensuite chaque cran retombe à portée (280 → 420 → 560 → 640). Pour un arrêt net à chaque cran, écrivez scroll-snap-type: y mandatory — ici aucune section ne dépasse la fenêtre, rien ne devient inatteignable. Garder la proximité est aussi un choix : le lecteur peut s'arrêter au milieu d'une section pleine.
Vertical Snap : quatre sections de 280 px dans une fenêtre de 280 px, y mandatory — chaque arrêt montre exactement une section, les points sont tous à 280 px d'écart. Ici les points sont à 280, 140, 140 et 80 px d'écart, le mode est la proximité, et trois arrêts sur cinq montrent plusieurs sections à la fois : la hauteur devient un signal de poids. Snap + Progress ajoute une barre et des points de navigation en JavaScript, mais son script calcule la section courante par Math.round(scrollTop / clientHeight) — il suppose des sections égales. Branché sur ces hauteurs, il donnerait l'index 1 aux arrêts 280 et 420 et l'index 2 aux arrêts 560 et 640 : deux points sur cinq jamais allumés. Pour une navigation ici, comparez scrollTop aux offsetTop réels des sections.
Parce que le conteneur ne défile pas au-delà de scrollHeight − clientHeight. Avec la dernière section en .sn-half, le contenu fait 780 px, la course 500, et le haut de cette section est à 640 : son point d'accroche est au-delà de la fin (mesuré : arrêt à 500, la section reste collée en bas du cadre, sous le quart). Le code vendu évite le problème en terminant par une .sn-full. Trois issues si votre dernière section doit être courte : scroll-snap-align: end sur elle (son bas s'aligne sur le bas du cadre — le réglage des trois exemples), un padding-bottom sur le conteneur égal à la différence (140 px pour une demi), ou une section vide de fin.