Introduction
En janvier 2026, un tutoriel Codrops appelé Efecto montrait comment dissoudre une photographie en un nuage de points mouvant. Dès l'été, les tutoriels « viral dithered website effect » étaient partout : un portrait qui se désagrège en grain noir et blanc, un logo fait de caractères ASCII qui respirent, une image de hero qui ne redevient nette que sous le curseur.
On me pose la même question chaque semaine : comment mettre ça sur mon site sans embarquer une vidéo de 3 Mo ? Cet article y répond deux fois. D'abord la théorie et 40 lignes de canvas à coller dans n'importe quelle page. Ensuite le générateur que je viens de publier, qui fait le même travail en trente secondes, animation et interaction souris comprises.

Pour comprendre l'algorithme, continuez. Pour l'effet sur votre page aujourd'hui, sautez au générateur.
1. Ce qu'est vraiment le dithering
Le dithering est un mensonge qui fonctionne. Vous avez deux couleurs et vous devez en montrer deux cents. Arrondir chaque pixel à la plus proche donne des aplats et des bandes. Le dithering, lui, répartit l'erreur d'arrondi sur les pixels voisins : à distance normale de lecture, l'œil moyenne les points et reconstitue une nuance qui n'a jamais existé.
Les journaux l'ont fait mécaniquement pendant un siècle, et la Game Boy le faisait en logiciel, en simulant avec quatre verts quelque chose qui se lit comme de la profondeur.
Le dithering ordonné (Bayer)
Une matrice fixe de seuils — 2×2, 4×4, 8×8 — est répétée sur l'image, et chaque pixel est comparé au seuil placé sous lui, puis allumé ou éteint. C'est un procédé sans mémoire : le pixel (10, 4) ignore ses voisins. D'où sa rapidité, d'où le fait que ce soit la seule option réaliste à soixante images par seconde, et d'où cette texture en croisillons qu'on associe au look rétro.
La diffusion d'erreur (Floyd-Steinberg, Atkinson)
On arrondit un pixel, on mesure de combien on s'est trompé, et on pousse cette erreur sur les voisins pas encore traités. Floyd-Steinberg répartit toute l'erreur sur quatre voisins. Atkinson — écrit chez Apple pour le premier Macintosh — n'en répartit que trois quarts : un peu moins de contraste, des blancs plus propres. Le rendu est organique, granuleux, sans grille visible. Le prix à payer : c'est séquentiel. Chaque pixel dépend du précédent, donc rien ne se parallélise et l'animer coûte vite cher.
Bayer pour tout ce qui bouge. Diffusion d'erreur pour une image fixe qu'on peut se permettre de calculer une seule fois. Cette seule décision explique l'essentiel de la suite.
2. Pourquoi la tendance revient en 2026
Trois choses se sont produites en même temps, et aucune n'est de la nostalgie.
- Tout s'est mis à se ressembler. Quatre ans de cartes en verre, de dégradés mesh et de heros SaaS aux coins arrondis. Une image tramée est bruyante d'une manière qui se lit comme un choix assumé.
- La plateforme a rattrapé son retard. Réécrire une image entière avec
getImageDatasaccadait. Sur un portable de 2026, un canvas de 600×400 tramé à chaque frame coûte une fraction de milliseconde. - La basse fidélité est devenue un signe de goût. Le même réflexe qui a ramené le grain argentique et les mises en page brutalistes. Une image en un bit dit « je sais ce que je fais avec le contraste », en quelques kilo-octets plutôt qu'en vidéo de fond.
3. Trois usages où ça vaut vraiment le coup
Un hero de portfolio qui se dévoile
L'usage le plus fort que je connaisse : tramer fortement l'image de hero, puis laisser la photo nette réapparaître sous le curseur. Le visiteur arrive sur une texture abstraite, bouge la souris par curiosité, et découvre l'image. Ça récompense un geste au lieu d'exiger un scroll. Sur mobile il n'y a pas de curseur : prévoyez le repli.
Un logo vivant sans être animé
Déposez un PNG transparent de votre logo, choisissez un grain grossier, ajoutez une animation lente de type breathe ou scan. Vous obtenez une marque qui bouge à la limite de la perception — idéal dans un pied de page ou un état de chargement, là où une vraie animation serait de trop et un logo figé du poids mort.
Un fond de section que personne n'a à télécharger
Tramez une texture ou un bloc de texte, passez-le dans une palette peu contrastée, servez-vous-en comme arrière-plan de section. Le rendu est généré dans le navigateur à partir d'une source légère : pas de grande image de fond à payer, et ça reste net à toutes les largeurs puisque le grain est calculé.

4. Le dithering Bayer en 40 lignes de canvas
Voici l'ensemble, sans aucune dépendance. Ajoutez un <canvas id="dither"></canvas> à votre page, pointez le script sur une image, et vous avez du dithering ordonné.
// Matrice de Bayer 4x4 : 16 seuils ordonnes, repetes sur toute l'image.
// Sans memoire d'un pixel a l'autre, donc assez leger pour tourner a 60 fps.
const BAYER4 = [
[ 0, 8, 2, 10],
[12, 4, 14, 6],
[ 3, 11, 1, 9],
[15, 7, 13, 5]
];
const canvas = document.querySelector('#dither');
const ctx = canvas.getContext('2d', { willReadFrequently: true });
const img = new Image();
img.crossOrigin = 'anonymous'; // utile si le fichier vient d'un autre domaine
img.src = 'photo.jpg';
img.onload = function () {
// 1. On reduit d'abord : c'est ce qui fixe la grosseur du grain.
const scale = 4; // un point de trame = 4 pixels a l'ecran
const w = Math.floor(img.width / scale);
const h = Math.floor(img.height / scale);
canvas.width = w;
canvas.height = h;
canvas.style.width = img.width + 'px';
canvas.style.imageRendering = 'pixelated'; // bords nets, pas de flou
ctx.drawImage(img, 0, 0, w, h);
// 2. On relit les pixels du canvas.
const frame = ctx.getImageData(0, 0, w, h);
const px = frame.data;
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
const i = (y * w + x) * 4;
// Luminance, ponderee comme l'oeil percoit le rouge, le vert et le bleu.
const lum = 0.299 * px[i] + 0.587 * px[i + 1] + 0.114 * px[i + 2];
// 3. On compare au seuil de cette case, ramene sur 0-255.
const threshold = (BAYER4[y % 4][x % 4] + 0.5) * 16;
const v = lum > threshold ? 255 : 0;
px[i] = px[i + 1] = px[i + 2] = v; // noir pur ou blanc pur
}
}
ctx.putImageData(frame, 0, 0); // 4. On repeint la trame dans le canvas.
};
Les trois réglages qui comptent
scale— le seul paramètre qui change le caractère du rendu. À 2 vous obtenez un grain fin de papier journal, à 8 de gros blocs façon Game Boy.- La taille de la matrice — remplacez le 4×4 par une matrice de Bayer 8×8 et la texture devient plus douce, moins visiblement quadrillée.
- La palette — l'extrait bascule en noir et blanc purs. Remplacez les deux valeurs de sortie par n'importe quelle paire de couleurs et vous tenez le terminal ambre ou le rendu papier.
L'extrait laisse volontairement de côté tout ce qui rend l'effet vivant : boucle d'animation, interaction au curseur, diffusion d'erreur, sortie ASCII, palettes. Quelques centaines de lignes de plus — exactement ce que le générateur écrit à votre place.
5. Le même effet en trente secondes
J'ai construit le générateur Dither & ASCII parce que les outils existants s'arrêtent une étape trop tôt. ASCII Magic, Dither Boy, ditherit et DotForge transforment une image en fichier tramé : PNG, GIF, MP4. Aucun ne donne un composant vivant, qui s'anime dans la page et réagit au visiteur.
Trois étapes :
- Déposez votre image — une photo, un logo, ou tapez une ligne de texte pour un traitement purement ASCII.
- Choisissez le traitement — Bayer, Floyd-Steinberg, Atkinson, halftone, lignes ou ASCII, puis une palette : mono, papier, ambre, terminal, cyan, Game Boy, CGA ou néon.
- Donnez-lui vie — une animation (flow, breathe, scan, noise, rain) et un comportement souris (reveal, repel, attract, ripple). C'est reveal qui fait apparaître la photo nette sous le curseur.
L'aperçu, tous les réglages et l'export PNG sont gratuits, sans compte. Premium débloque une seule chose : l'export du code, un bloc HTML autonome d'environ 15 Ko, sans dépendance, à coller dans n'importe quelle page.
Aperçu, réglages et export PNG ne coûtent rien. Seul l'export du bloc HTML est Premium.
6. Performance et accessibilité
Tramez à la résolution du grain
Le coût est proportionnel au nombre de pixels traités : la réduction de l'étape 1 est votre levier de budget. Un canvas de 400×300 étiré sur un hero de 1600 px coûte quatre fois moins qu'un 800×600, et à gros grain la différence est invisible. Ne tramez jamais à la résolution de l'écran.
Passez willReadFrequently
Récupérer le contexte 2D avec { willReadFrequently: true } prévient le navigateur que vous allez appeler getImageData en boucle : il place alors la mémoire du canvas là où ces lectures sont bon marché. L'oublier est la première cause d'un dithering animé qui saccade.
Respectez prefers-reduced-motion
Flow, noise et rain sont exactement le mouvement de fond continu qui gêne certains visiteurs. Encadrez la boucle par un test et affichez une image fixe. Le rendu tramé survit très bien sans mouvement : c'est tout l'intérêt d'être une texture et pas une vidéo.
Le mobile, et le canvas reste décoratif
Les modes pilotés par le curseur n'ont rien à quoi se raccrocher sur un écran tactile : soit l'effet se fige sur une bonne image, soit le point d'interaction suit un trajet automatique lent. Et tout ce qu'un moteur de recherche ou un lecteur d'écran doit lire — nom, accroche, texte du logo — reste du vrai HTML posé par-dessus, avec aria-hidden="true" sur le canvas.
Questions fréquentes
Quelle différence entre dithering et halftone ?
Le halftone est une famille de dithering, celle de l'imprimerie : des points de taille variable sur une grille régulière, d'où l'aspect d'une photo de journal vue à la loupe. Le dithering est l'idée plus large de simuler des nuances avec une palette limitée — taille des points, seuils répétés (Bayer) ou propagation de l'erreur (Floyd-Steinberg).
Un canvas tramé pénalise-t-il mes Core Web Vitals ?
Pas si vous le dimensionnez correctement. L'élément canvas ne pèse que quelques octets de HTML, et l'image source reste petite puisque vous la réduisez de toute façon. Le risque est le décalage de mise en page, pas le poids : donnez au canvas des dimensions explicites en CSS pour qu'il réserve sa place avant l'exécution du script.
Est-ce que ça marche sur un logo PNG transparent ?
Oui, et c'est même un des meilleurs usages. Lisez le canal alpha en même temps que la luminance et traitez les pixels totalement transparents comme « éteints », pour que le grain épouse la forme de la marque. Dans l'extrait ci-dessus, ajoutez un test sur px[i + 3].
Le générateur dither d'Effect.Labs est-il gratuit ?
Oui : import, tous les algorithmes, toutes les palettes, toutes les animations et l'export PNG, sans compte. Premium débloque une seule chose — l'export de l'effet en bloc HTML autonome pour votre propre site.
Conclusion
Le dithering est vieux, peu coûteux et réellement utile. La raison de s'en servir n'est pas la référence rétro mais l'économie : une texture calculée dans le navigateur ne pèse rien, s'adapte à toutes les largeurs, et réagit au visiteur comme une image de fond ne le fera jamais.
Prenez l'extrait ci-dessus pour avoir le principe en main. Quand vous voudrez l'animation, le reveal au curseur et les palettes sans écrire les centaines de lignes restantes, le générateur est à un clic.
Des dizaines d'effets glitch, grain et distorsion sont prêts à copier dans la bibliothèque Effect.Labs, aperçu live et code vanilla.