Scroll✨ Premium

Zoom & Blur

Trois images-clés symétriques sur animation-timeline: scroll() dans une boîte de 280 px : le cercle n'est net, entier et à ses 200 px qu'à mi-course (260 px sur 520) — ×0,5, flou 10 px, opacité .3 avant ; ×2, flou 10 px, .3 après. Un point de mise au point, pas un zoom. Zéro JavaScript.

CSSZoomBlur

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

Lot phare d'une vente aux enchères — page du catalogue d'une maison de ventes — Zoom & Blur exemple 1

① Lot phare d'une vente aux enchères — page du catalogue d'une maison de ventes

QuandPage de la vente : nom de la maison et date en barre, estimation et frais en haut de la fiche, puis la photo du lot qui passe de flou-petit à net-plein au centre du cadre et file en grossissant vers la provenance, les dimensions et le bouton d'enchère.
PourquoiL'acheteur ne voit l'œuvre nette qu'à une seule position de défilement : il s'y arrête, comme devant la vitrine — fx-0590 ne cesse de grossir et n'offre aucune position de repos à l'œil. L'état net étant l'état de base, la fiche reste lisible sur Firefox et sous prefers-reduced-motion.
RéglagesCode vendu intact (animation-timeline: scroll() sur .sdc-zoom-element) ; barre de 48 px, boîte de 312 px, plateau remplacé par une colonne bloc de 250 px · tableau de 200 px · bloc de 250 px, 16 px d'écart : 732 px de contenu, course 420, net à 210 ; le cercle devient un cadre doré (border-radius: 3px, dégradé, box-shadow inset) autour d'une marine en dégradés ; textes en z-index: 1 — en bout de course le tableau ×2, flou à 30 %, s'efface derrière la provenance. Fond ivoire, serif.
Échantillon sous le microscope — module de biologie d'un cours en ligne — Zoom & Blur exemple 2

② Échantillon sous le microscope — module de biologie d'un cours en ligne

QuandCours de SVT : module et progression en barre, une consigne — faites défiler comme vous tourneriez la vis micrométrique —, puis la lame d'épiderme d'oignon, floue et petite, nette et à sa taille quand la molette atteint la bonne mise au point, refloutée en grossissant au-dessus de la liste de ce qu'il faut repérer.
PourquoiC'est exactement la vis micrométrique d'un microscope : net à une seule position, flou de part et d'autre — la troisième image-clé refloute la lame dès que l'élève dépasse le point, et c'est ce dépassement qui lui apprend qu'il y a un réglage à trouver. fx-0551 Blur to Clear ne fait que le premier demi-mouvement et reste net ensuite : la mise au point ne peut pas être ratée, donc rien à régler.
RéglagesBoîte de 314 px sous une barre de 46 px, même colonne 250 · 200 · 250 (course 418, net à 209) ; le cercle garde son border-radius: 50% et devient le champ de l'oculaire : deux repeating-linear-gradient pour les parois (cellules de 38 × 21 px), sept noyaux en span, bague noire en box-shadow et vignettage inset ; fond clair, sans-serif, accent #2563eb.
Bague sur la fiche d'un joaillier — le bijou passe en focus entre deux paragraphes — Zoom & Blur exemple 3

③ Bague sur la fiche d'un joaillier — le bijou passe en focus entre deux paragraphes

QuandFiche d'un solitaire : l'histoire de la pierre en premier paragraphe, puis la bague qui vient au point au milieu du cadre, puis métal, pierre, taille, prix et le bouton de rendez-vous, sous le bijou qui s'efface en grandissant.
PourquoiLe moment net est exactement à mi-course : le rédacteur place ses deux paragraphes de part et d'autre et sait où l'œil se pose — fx-0580 Zoom on Scroll grossit jusqu'à ×5 sans jamais redevenir discret.
RéglagesBoîte de 310 px sous une barre de 50 px, course 422, net à 211 ; le cercle perd son fond (background: none) et contient l'anneau (150 px, border: 16px or à quatre teintes) et le saphir ovale (68 × 60 px, radial-gradient, reflet en ::after) ; caractéristiques en grille 2 × 2 ; fond #0f0d0b, serif, or #d4b15f.

Comment ça marche

Quatre éléments : le cadre .demo-preview (flex centré, min-height: 300px, position: relative, fond #0a0a0f, texte blanc, sans-serif), la boîte .sdc-scroll-container (100% × 280px, overflow-y: auto, scroll-behavior: smooth, barre de 4 px en ::-webkit-scrollbar), le plateau .sdc-zoom-content (800 px, flex centré) et le cercle .sdc-zoom-element : 200 × 200 px, border-radius: 50%, dégradé 135° #8b5cf6 → #ec4899, sans texte. Deux étiquettes en dur : .sdc-zoom-text « Zoom in → net → zoom out » (11,5 px, blanc à 30 %, à 40 px du bas du plateau) et .sdc-scroll-hint « Scrollez ↓ » (10,4 px, ancrée au cadre, pulsation .3 → .7 en 2 s). Course : 800 − 280 = 520 px. Champ JavaScript vide, aucun var(--…), aucun id ; mesuré dans une page vierge (fond blanc et sombre, 1 280 et 390 px) : aucune requête, aucune erreur console dans Chromium 151, WebKit 26.5 et Firefox 153.

Une règle fait tout : animation-name: sdcZoomBlur avec animation-timeline: scroll() — l'animation n'avance plus avec le temps mais avec la position du premier ancêtre défilant, la boîte ; animation-duration: auto et animation-range: normal l'étalent sur toute la course, linear relie les images en droite. Trois images-clés : 0% { transform: scale(.5); filter: blur(10px); opacity: .3 }, 50% { transform: scale(1); filter: blur(0); opacity: 1 }, 100% { transform: scale(2); filter: blur(10px); opacity: .3 }. Mesuré par crans de 100 px : ×0,69 / 6,2 px / .57, ×0,88 / 2,3 px / .84, ×1,15 / 1,5 px / .89, ×1,54 / 5,4 px / .62, ×1,92 / 9,2 px / .35, puis ×2 / 10 px / .3 ; à 260 px exactement, ×1 / 0 / 1. Flou et opacité varient au même rythme des deux côtés (3,8 px et .27 par 100 px), pas l'échelle : +0,19 par 100 px avant le point net (100 → 200 px), +0,38 après (200 → 400 px). Le net existe à une seule position, et c'est aussi l'état de base de l'élément : là où la timeline n'existe pas, c'est lui qui s'affiche.

Le cercle est centré à 400 px du haut d'un plateau dont la boîte montre 280 : au repos, réduit à 100 px (350–450 px), il est sous le pli — boîte sombre vide, plus l'indice. Mesuré : il entre par le bas à 59 px de défilement, est centré et net à 260 px avec 40 px de marge, grossit et sort par le haut — à 520 px, ses 400 px vont de −320 à 80 px, il reste une calotte floue de 80 px à 30 %, et l'étiquette n'apparaît que sur les 41 derniers pixels. Point net et centrage sont liés : l'image 50 % tombe à mi-course, le plateau met le cercle à mi-hauteur, donc au centre de la boîte à cet instant ; déplacer l'un sans l'autre donne un objet net hors cadre. En largeur, ×2 fait 400 px : sous 400 px de boîte, overflow-y: auto (qui implique overflow-x: auto) ouvre une piste horizontale — mesuré 13 px à 390 px de large. scroll-behavior: smooth ne lisse que les positions posées par script ou ancre. Sans id ni script, plusieurs copies par page pilotent chacune leur boîte.

Accessibilité

  • prefers-reduced-motion absent du code : mesuré sous émulation, mêmes valeurs (×0,5 → ×2, flou 10 px), indice toujours pulsant. Rien n'est caché — cercle visible dès 59 px, net à 260 — et rien ne bouge sans le geste du lecteur (WCAG 2.3.3). Le point sensible est le flou : 10 px sur un contenu réel le rendent illisible sur deux tiers de la course. Ajoutez @media (prefers-reduced-motion: reduce) { .sdc-zoom-element { animation: none } .sdc-scroll-hint { animation: none } } : le cercle reste alors à son état de base, 200 px, net, opaque — ce que voit Firefox.
  • Clavier : mesuré, Tab focalise la boîte sans tabindex dans Chromium (anneau outline: auto 1px) et Firefox 153 ; flèche bas = 40 px (51 dans Firefox), PageDown et Espace = 245 (252), Fin = 520, Début = 0. WebKit 26.5 ne la focalise pas sans tabindex="0" (focus sur body, flèches inertes ; 40 px par flèche avec l'attribut) : ajoutez-le, avec un :focus-visible et un aria-label. Aucun cran ne s'arrête sur le point net (245 puis 490 px) : au clavier on ne voit jamais l'objet net — voir « Tenue du point net ».
  • Contraste : l'indice « Scrollez ↓ » (10,4 px, blanc à 30 % sur #0a0a0f) vaut 2,6:1 au repos, de 1,2:1 à 1,8:1 sous la pulsation (l'opacité .3 → .7 se multiplie aux 30 % de la couleur) ; l'étiquette (11,5 px, 30 %) reste à 2,6:1. Décoratifs : aria-hidden="true", ou 70 % (9,7:1). Le cercle ne porte aucun texte ; un contenu à lire n'y est net qu'autour de 260 px, le flou dépasse 5 px avant 130 et après 390 — écrivez l'information aussi hors du cercle.
  • Lecteurs d'écran et repli : le cercle est un div vide, rien à annoncer ; s'il devient une image porteuse de sens (lot, bague, lame), donnez-lui role="img" et un aria-label — un lecteur d'écran ne fait pas la mise au point. Les deux étiquettes sont lues telles quelles, en français et en franglais. Sans animation-timeline (Firefox, Chrome avant 115), le cercle est à 200 px, net, opaque, et défile avec le plateau : tout reste visible et atteignable, sans effet.

Compatibilité navigateur

CSS seul : animation-timeline: scroll(), animation-duration: auto, animation-range (Scroll-driven Animations), filter: blur(), transform: scale(), opacity, overflow-y: auto, scroll-behavior, flexbox, @keyframes. Zéro JavaScript, zéro dépendance. Chrome et Edge 115+, Safari et iOS 26+ (mesuré dans WebKit 26.5 : mêmes valeurs que Chromium). Firefox : aucune version. Mesuré dans Firefox 153 : CSS.supports() répond faux pour animation-timeline: scroll(), animation-duration: auto et animation-range, les trois déclarations sont ignorées ; l'animation dure 0 s sans remplissage (animation-fill-mode: none) et l'élément retombe sur son état de base : transform: none, filter: none, opacity: 1. Le visiteur Firefox voit un cercle de 200 px, net et opaque, qui traverse la boîte comme un contenu ordinaire — entré à 20 px, centré à 260, sorti à 500 — puis l'étiquette. Rien de caché, rien de manquant : pas d'effet. Aucun @supports dans le code vendu ; @supports not (animation-timeline: scroll()) { .sdc-zoom-element { animation: none } } donnerait exactement le même rendu.

Chrome 115+✓ Complet
Firefox (toutes versions)✓ Sans effet : cercle net à 200 px, tout le contenu visible
Safari 26+✓ Complet
Edge 115+✓ Complet
Mobile iOS 26+✓ Complet (défilement tactile de la boîte)
Android Chrome 115+✓ Complet

Sans animation-timeline (Firefox, Chrome et Edge avant 115, Safari avant 26) : cercle à 200 px, net, opaque, qui défile avec le plateau — tout visible, rien ne bouge. Sans filter, zoom et fondu subsistent. Là où overflow n'est pas honoré (clients mail), le plateau de 800 px s'affiche entier, cercle net au milieu.

Le code

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

index.html — structure
<div class="demo-preview">
  <div class="sdc-scroll-container">
    <div class="sdc-zoom-content">
      <div class="sdc-zoom-element"></div>
      <span class="sdc-zoom-text">…</span>
    </div>
  </div>
  <span class="sdc-scroll-hint">…</span>
</div>
Débloquer le code complet — 9,90 € HT/mois

Le code complet HTML + CSS + JS de Zoom & Blur, 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
Images-clés (CSS — @keyframes sdcZoomBlur) ×0,5 / 10 px / .3 → ×1 / 0 / 1 → ×2 / 10 px / .3 Trois valeurs indépendantes : scale(.85) → 1 → 1.25 pour une mise au point discrète, blur(4px) pour un flou plus photographique, opacity: .6 pour garder l'objet présent aux extrémités. Gardez l'image 50 % à ×1 / 0 / 1 : c'est l'état de base, celui de Firefox et de reduced-motion.
Position du point net (CSS — l'image 50%, et le centrage du plateau) 50 % = 260 px, cercle centré à 400 px du plateau Mesuré avec l'image à 35% : net à 182 px, mais cercle à 118–318 px de la boîte, pas centré (centre à 218 au lieu de 140). Centre de l'objet = course × fraction + 140 px, soit 322 px pour 35 % — padding-top sur le plateau ou margin-top négatif sur le cercle.
Tenue du point net (CSS — deux images-clés 40%, 60%) aucune : net sur une seule position Mesuré avec 40%, 60% { transform: scale(1); filter: blur(0); opacity: 1 } : net de 208 à 312 px, 104 px de course au lieu d'une position — un cran de flèche (40 px) ne peut plus le manquer. Le flou reprend à 3,75 px 130 px de part et d'autre.
Course et plage (CSS — .sdc-zoom-content { height: 800px }, .sdc-scroll-container { height: 280px }, animation-range) 520 px, animation-range: normal Course = plateau − boîte ; le point net reste à mi-course. 1 200 px de plateau = 920 px de course, mouvement deux fois plus lent ; une boîte plus haute montre le cercle plus tôt (à 280 px, il n'entre qu'après 59 px). animation-range: 20% 80% concentre l'animation au milieu, mais hors plage l'élément retombe à l'état de base (mesuré : 200 px net à 65 px, saut à 100 px flou à 104) — ajoutez animation-fill-mode: both.
Rythme (CSS — animation-timing-function: linear) linear S'applique entre chaque paire d'images. Mesuré en ease-in-out : ×0,96 / 0,8 px / .94 à 208 px (contre ×0,9 / 2 px / .86 en linear), ×1,08 à 312 — le cercle s'attarde près du net et se précipite vers les extrémités.
Taille, forme et contenu (CSS — .sdc-zoom-element { width/height: 200px; border-radius: 50% }) 200 px, cercle, dégradé #8b5cf6 → #ec4899 Tout le contenu (img, SVG, enfants) est zoomé et flouté avec la boîte : une image de 200 px est étirée à 400 px en bout — fournissez 400 px de source. Sous 400 px de boîte, débordement horizontal (mesuré 13 px à 390 px) : overflow-x: hidden. Sans id, plusieurs instances par page fonctionnent.
Défileur et textes (CSS — scroll(), scroll-behavior: smooth, .sdc-scroll-hint, .sdc-zoom-text) défileur le plus proche, smooth, « Scrollez ↓ » et « Zoom in → net → zoom out » scroll() prend le premier ancêtre défilant ; scroll(root) pilote par la page, view() par la traversée de la fenêtre (voir la FAQ). smooth ne lisse que les positions posées par script ou ancre. Les deux textes sont en dur (l'étiquette en franglais, visible sur les 41 derniers pixels) : traduisez-les ou supprimez les deux span.

FAQ

Parce que point net et centrage sont liés : l'image 50 % tombe à mi-course (260 px) et, pour que le cercle soit alors au centre de la boîte, il doit être à mi-hauteur du plateau (400 px sur 800) — donc, au repos, à 350–450 px réduit à 100 px, sous les 280 px visibles. Mesuré : entrée par le bas à 59 px, calotte floue de 49 px à 100, entier et net à 260. Trois remèdes : une boîte plus haute (400 px) le montre d'emblée ; du contenu au-dessus (les trois scènes de cette page mettent 250 px de texte avant l'objet) fait de son entrée floue une annonce ; animation-range: 20% 80% avec animation-fill-mode: both le tient à ×0,5 flou tant qu'il n'est pas dans la boîte. Le piège : remonter le cercle sans toucher aux images-clés — net à 260 px, mais 140 px trop haut, coupé par le bord.
Même squelette : boîte de 280 px, plateau de 800 px, animation-timeline: scroll(), linear, animation-range: normal, pas de JavaScript, même sort sur Firefox. Mais fx-0590 n'a que deux images-clés, scale(1) → scale(2.2) et border-radius: 20px → 4px sur un carré de 120 px, sans filter ni opacity : mesuré ×1,6 à 260 px et ×2,2 à 520, où il ne reste que 12 px du carré dans la boîte — le plus grand est le dernier état, sans sticky malgré son nom. fx-0563 ajoute la troisième image, le flou et l'opacité : l'objet n'est lisible qu'à une position et brumeux des deux côtés — un point de repos pour l'œil, une mise au point, pas un zoom. fx-0590 pour faire grandir un objet jusqu'au bout (une révélation), fx-0563 pour le faire passer — apparaître, se lire, s'effacer — entre deux blocs de contenu.
Oui, en changeant la timeline. scroll(root) prend le défileur du document, mais la course devient la page entière et le point net tombe à 50 % de la page, rarement là où est l'objet. La bonne réponse est animation-timeline: view() : la timeline devient la traversée de la fenêtre par l'élément — 0 % quand il entre par le bas, 100 % sorti par le haut, 50 % au centre. Mesuré avec cette seule ligne changée, dans une page de 3 100 px : ×0,7 / 6 px / .58 à 200 px de son entrée, ×0,95 / 1 px / .93 à 50 px du centre, ×1,4 / 4 px / .72 en remontant, ×1,9 / 9 px / .37 avant de sortir. Plus de boîte ni de plateau : supprimez .sdc-scroll-container et .sdc-zoom-content, gardez overflow-x: hidden sur la page pour les 400 px de large en bout de course. Même prise en charge : Chrome 115, Safari 26, pas Firefox.