Dégradés granuleux
Les dégradés numériques lisses évoquent "l'ordinateur". Une fine couche de bruit leur donne un aspect imprimé ou argentique, et masque les bandes (stries visibles là où un dégradé passe d'un niveau de couleur 8 bits au suivant).
Vous faites tout le travail. La personne ne fait que regarder et choisir. Ne demandez jamais les modes de fusion, l'opacité ou les chiffres. La personne prend trois types de décisions, et rien d'autre :
- Quels arrière-plans (uniquement lorsque vous avez scanné l'ensemble du site).
- S'il faut voir un avant et un après d'abord, ou simplement l'appliquer.
- Quelle option est la meilleure dans l'aperçu.
Comment penser à cela
-
Le grain est une texture, pas une couleur. Il ne doit pas éclaircir, assombrir ou teinter. Le bruit est centré sur un gris moyen, donc le décalage de luminosité doit être proche de 0. Il ne peut pas être utilisé pour du noir ou blanc pur, et le rapport le mentionne.
-
Mesurez ce qui est visible, pas l'opacité. Le grain visible est l'étendue de L* (luminosité CIELAB, 0-100), et L* est perceptif, donc le même nombre semble similaire sur n'importe quelle couleur. En dessous d'environ 0,45, personne ne peut le voir. Les cibles sont 0,5 / 0,8 / 1,4 pour Subtle / Medium / Strong.
-
Even est important sur les dégradés qui vont du clair au foncé. Overlay place la plupart du grain sur les parties claires. Even choisit le mélange (généralement soft-light) qui le répartit plus uniformément. Les gens ont tendance à le préférer.
-
Le grain appartient à l'arrière-plan. Il se trouve juste au-dessus de l'arrière-plan, en dessous de tout le reste, et va partout où va l'arrière-plan. Si l'arrière-plan s'estompe, le grain s'estompe avec lui.
-
Il s'adapte à l'écran de chaque visiteur. Les sites Web ne peuvent pas distinguer OLED de LCD, mais le CSS peut détecter les écrans HDR (la plupart des téléphones OLED, ordinateurs portables XDR) et le réglage de contraste élevé. Le CSS inclut ces media queries :
- les arrière-plans sombres reçoivent un peu moins de grain sur les écrans HDR
- le réglage de contraste élevé reçoit moins de grain
- l'impression le désactive
Tout est en CSS, sans script sur le site en direct.
-
Ignorez ce que le grain ne peut pas aider :
- les petits éléments (boutons, badges, icônes)
- le texte en dégradé
- les voiles et fondus transparents sur des photos
- les motifs à rayures et à hachures
1. De quelle manière ont-ils demandé ?
- Un seul endroit ("le hero a l'air plat", "ajoute du grain au footer") : allez à Trouver un arrière-plan.
- L'ensemble du site ou de l'application ("passe en revue ma base de code", "vérifie tous mes dégradés", "fais tout le site") : allez à Scanner l'ensemble du site.
2a. Trouver un arrière-plan
Trouvez l'élément qui peint réellement l'arrière-plan. Vérifiez :
- l'élément lui-même, et ses
::beforeet::after - les couches de pleine taille à l'intérieur ou derrière lui (les sections obtiennent souvent leur couleur d'un div séparé positionné en absolu)
Avec un outil de navigateur, listez les candidats :
[...document.querySelectorAll('#section, #section *')].flatMap(e => [null, '::before', '::after'].map(p => [e, p, getComputedStyle(e, p)]))
.filter(([, p, c]) => (!p || c.content !== 'none') && (c.backgroundImage !== 'none' || c.backgroundColor !== 'rgba(0, 0, 0, 0)'))
.map(([e, p, c]) => `${e.tagName.toLowerCase()}${e.id ? '#' + e.id : ''}.${[...e.classList].join('.')}${p || ''} | ${c.position} | opacity ${c.opacity} | ${(c.backgroundImage !== 'none' ? c.backgroundImage : c.backgroundColor).slice(0, 80)}`)
Sans navigateur, lisez le CSS. Dans les deux cas, recherchez dans le CSS d'autres versions de cet arrière-plan : les media queries (les mises en page pour téléphone échangent souvent le dégradé) et les règles de mode sombre. Notez-les pour l'étape 5.
Puis allez à l'étape 3.
2b. Scanner l'ensemble du site
node <dossier de ce skill>/scripts/scan.mjs <dossier du projet>
Il lit les feuilles de style (règles, media queries, propriétés personnalisées), le balisage et les composants (classes de dégradé Tailwind, styles en ligne, CSS-in-JS) en environ une seconde. Il trie ce qu'il trouve en quatre groupes :
- Bons candidats : grands arrière-plans.
- À voir : taille inconnue d'après le code.
- Déjà granuleux.
- Ignorer, avec la raison.
Il liste également quelles pages chargent chaque feuille de style. Ajoutez --json pour les données complètes.
Triez vous-même ceux "à voir". Avant d'afficher la liste, triez-les en fonction de ce que vous pouvez voir. Avec un outil de navigateur, mesurez leur taille sur la page. Sinon, lisez le balisage. Déplacez chacun vers bon ou ignorer. N'envoyez pas à la personne une liste de choses que vous auriez pu vérifier.
Ensuite, montrez la liste, courte, une ligne chacun, en termes simples, groupée par page. Par exemple :
J'ai trouvé 6 arrière-plans qui pourraient recevoir du grain :
- Accueil, section tour : dégradé foncé qui s'estompe
- Accueil, hero : lueur radiale sombre
- Durabilité, en-tête : dégradé vert-noir
- Carrières, bande "fait ici" : dégradé orange-noir
Ignoré 12 : boutons, texte en dégradé, voiles de photo et motifs à rayures. La page de citation a déjà du grain, mais à un niveau que personne ne peut voir, donc je le referais.
Ensuite, laissez-les choisir. Si vous disposez d'un outil de questions à choix multiples (AskUserQuestion dans Claude Code), utilisez-le :
- Demandez "Quels arrière-plans devraient recevoir du grain ?" avec Tous (Recommandé) en premier.
- Pour jusqu'à 3 éléments supplémentaires, listez chacun comme une option avec la sélection multiple activée.
- S'il y en a plus de 4, demandez d'abord "Tous, ou choisir ?" ; sur "choisir", posez des questions à sélection multiple de 4 éléments maximum chacune.
Sans l'outil, demandez-leur de répondre par "tous" ou les numéros.
3. Demander : avant/après, ou juste appliquer ?
Demandez une fois, pour tout ce qui a été choisi : "Voulez-vous voir un avant et un après d'abord, ou dois-je simplement appliquer la meilleure option pour chacun ?" Utilisez l'outil à choix multiples si vous l'avez, avec Montrez-moi d'abord (Recommandé) et Appliquez simplement.
Les outils ci-dessous nécessitent Node 22+ et un Chrome, Chromium, Edge ou Brave sur la machine (trouvé automatiquement ; CHROME_PATH le remplace). Ils ouvrent les pages en mode headless, donc le site doit être accessible : un serveur de développement en cours d'exécution, une URL de staging, ou file:// pour du HTML simple. Rien n'est ajouté au site.
4. Afficher l'avant/après
Montrez-moi d'abord : la page de révision
Exécutez-le en arrière-plan (il attend la personne) avec une --url par page et les sélecteurs de cette page après :
node <skill>/scripts/review.mjs --url http://localhost:3000/ --selector ".hero" --selector ".footer-band" \
--url http://localhost:3000/about --selector ".about-header"
- Il prend les photos lui-même. Pour chaque arrière-plan, il photographie la page telle quelle et avec chaque option, plus ce que les écrans HDR et le réglage de contraste élevé donnent. Cela prend environ 10 à 30 secondes par page.
- Ensuite, il ouvre une page de révision locale dans le navigateur et imprime son adresse ; donnez également le lien à la personne.
- Chaque arrière-plan reçoit une carte avec :
- un curseur avant/après
- Zoom sur le banding, qui agrandit la zone qui présente le plus de bandes (le grain fin est invisible dans une image réduite)
- les options sous forme d'onglets, avec celle recommandée marquée d'une étoile
- un commutateur d'écran
- les chiffres mesurés, et un "Pourquoi" avec le rapport
- "Terminé, envoyez mes choix" envoie les choix directement. Pas de copier-coller.
Dites-leur en une ligne quoi faire : "Faites glisser sur chaque image, essayez Zoom, choisissez-en un par arrière-plan, puis appuyez sur Terminé." Lorsque la commande se termine, sa sortie contient les choix, le CSS pour chaque arrière-plan, et un dossier de référence (baseline) par arrière-plan pour la vérification à l'étape 7.
Montrez également une image dans le chat. Chaque dossier de référence contient compare-<option>.png :
- l'avant/après complet
- un détail agrandi
- le même détail avec son contraste étiré, de sorte que le banding apparaît sous forme de stries et le grain sous forme de bruit
- les chiffres mesurés
Envoyez celui recommandé à la personne (avec un outil d'envoi de fichier si vous en avez un ; sinon, donnez le chemin). C'est la preuve que le changement est réel.
Appliquez simplement
Prenez d'abord la référence et les photos, afin que le résultat puisse être vérifié et montré :
node <skill>/scripts/shoot.mjs --url http://localhost:3000/ --selector ".hero" --option recommended --out ./grain-shots
Il imprime une ligne par photo (grain, luminosité, largeur de strie) et écrit <out>/<selector>/ avec report.json (le rapport, le CSS pour chaque option, celle recommandée) et compare-<option>.png. Utilisez le CSS recommandé de report.json.
Pas de Chrome, ou le site est inaccessible en mode headless
Repliez-vous sur l'aperçu dans la page : copiez dist/grain-page.js à côté des propres scripts du site (vérifiez qu'il se charge, 200 pas 404), ajoutez <script src="/js/grain-page.js" data-grain=".hero | .footer" defer></script>, et demandez-leur d'ouvrir la page avec ?grain. Il montre les mêmes options avec une poignée déplaçable sur la page réelle ; Copier les choix copie grain: <option> + l'apparence pour chaque arrière-plan, que vous redirigez dans node <skill>/scripts/grain.js --look - pour le CSS. Supprimez la balise et le fichier ensuite.
Sans navigateur du tout, écrivez vous-même l'apparence et exécutez grain.js dessus :
{ "selector": ".hero", "kind": "gradient", "shape": "linear",
"colours": [{ "colour": "#323435", "pos": 0 }, { "colour": "#141617", "pos": 1 }],
"lengthPx": 900, "background": "linear-gradient(...)", "behind": "#ffffff",
"solidBase": true, "position": "relative", "freePseudo": "::after", "moves": null }
ou node grain.js --colours "#323435,#2a2c2d@24%,#141617" --length 900 --selector ".hero" [--shape radial] [--fade-over "#fff"] [--option even].
Ce que le moteur décide, pour que vous n'ayez pas à le faire
| Situation | Ce qu'il fait |
|---|---|
| Dégradé ou couleur unie sur un élément | Une seule couche : le bruit devient la couche d'arrière-plan supérieure de l'élément (background-blend-mode), maintenue dans une propriété personnalisée --grain. Une valeur est ajoutée à chaque liste d'arrière-plan, donc les tailles, positions et mélanges propres à la page sont conservés. Il ne peut pas couvrir le texte. |
| L'arrière-plan s'estompe | La même couche unique, donc le grain s'estompe avec lui. Le rapport donne le grain à chaque étape de l'estompage. |
| Dégradé transparent sans rien de solide en dessous | Sa propre couche (un ::after/::before libre, ou un élément enfant) afin qu'il se mélange avec ce qui apparaît au lieu de virer au gris. |
| Arrière-plan photo ou image | Un pseudo-élément libre, ou un élément enfant si les deux sont pris. |
<img>/<video> remplissant l'élément, ou un arrière-plan sur un pseudo-élément | Un élément enfant à z-index: -1 dans un hôte isolé. |
| Noir ou blanc pur | Overlay et soft-light ne peuvent pas ajouter de grain là, donc il utilise screen ou multiply avec un petit décalage de luminosité, et le mentionne. |
| Grain inégal sur le dégradé | Recommande Even, si Even est clairement plus uniforme. Even est masqué lorsqu'il serait identique à Medium. |
| Risque élevé de banding | Indique si le grain choisi brise les stries. Strong en fait plus. |
| Ancienne couche de bruit dans le même arrière-plan | La remplace. Si l'ancien bruit se trouve ailleurs (un pseudo-élément), il demande de le supprimer. |
| Partie de l'arrière-plan dessinée dans une scène WebGL/canvas (un sol 3D, un fond de shader) | Le CSS derrière le canvas ne peut pas l'atteindre, donc la partie canvas semble lisse ou tachetée à côté d'un ciel granuleux. Vous l'ajoutez : dans le fragment shader de ce matériau, après la conversion d'espace colorimétrique, soft-light sur la même tuile de bruit dans l'espace écran (gl_FragCoord.xy / tilePx, tuile = 200 × ratio de pixels du rendu). Lisez la tuile et la quantité depuis la propriété personnalisée --grain de la page, afin que les quantités pour téléphone, HDR et contraste élevé soient reportées, et relisez-la lors du redimensionnement. Mesurez en rendant une image et en lisant les pixels. |
| Écrans HDR, contraste élevé, impression | @media (dynamic-range: high) et @media (prefers-contrast: more) résolvent à nouveau la quantité pour ces écrans, avec le même mélange. @media print la désactive. Une règle qui donnerait le même résultat est omise. |
Les couleurs sont pondérées par la part du dégradé qu'elles couvrent. Un reflet fin ne compte pas autant qu'une grande zone sombre, donc les versions téléphone et ordinateur de bureau de la même section reçoivent le même traitement.
5. Appliquer
- Placez chaque bloc CSS là où cet arrière-plan est défini, avec son commentaire.
- Conservez l'expression d'arrière-plan propre au projet. Le moteur travaille à partir de valeurs calculées, donc remettez
var(--slate)ou lelinear-gradient(...)d'origine là où la sortie répète un long dégradé résolu. - Faites chaque version de chaque arrière-plan (téléphone, mode sombre). Le CSS à une seule couche va sur le même sélecteur dans la même media query. Mesurez chaque version avec
--phoneou--colourssi elle diffère. - Méthode enfant : ajoutez
<div class="grain-layer" aria-hidden="true"></div>là où le commentaire le dit (dans un composant, dans son balisage). - Utilisez une propriété personnalisée pour une URL de bruit répétée. Si plusieurs règles utilisent la même, définissez-la une fois.
- Si le rapport liste "Fonds sur le dessus", donnez à chacun le même grain que décrit, sinon il bandera à nouveau là où il est le plus sombre.
- Supprimez tout ce qui est temporaire (une balise d'aperçu,
grain-page.js).
6. Vérifier, à chaque fois
Avant de dire que c'est terminé, vérifiez chaque arrière-plan par rapport à sa référence :
node <skill>/scripts/check.mjs --url http://localhost:3000/ --selector ".hero" --baseline <dossier de référence> [--option even]
Il photographie à nouveau la page et imprime RÉUSSI/ÉCHEC pour chacun de ces points :
- La couche de grain est dans la page (le CSS est chargé et sur le bon sélecteur).
- Aucune nouvelle erreur sur la page.
- Le grain est proche de la quantité attendue.
- La luminosité n'a pas bougé.
- Les stries se sont rétrécies.
- Rien en dehors de l'arrière-plan n'a changé.
- Aucun élément n'a bougé ou changé de taille.
Il écrit check.png, avant vs maintenant. En cas d'ÉCHEC, corrigez et relancez la vérification ; ne signalez pas de succès après un échec. Si un ÉCHEC ne peut pas être corrigé, dites exactement à la personne quel test a échoué et pourquoi.
7. Rapporter
Une ou deux phrases par arrière-plan, ou une courte liste pour l'ensemble du site : ce que c'est, ce qui a été choisi et pourquoi. Ajoutez le résultat mesuré de la vérification (par exemple "grain 0,83 L*, stries 80px → 0,7px, rien d'autre n'a changé") et envoyez check.png ou l'image compare. Dites une fois que le grain s'adapte aux écrans HDR et au réglage de contraste élevé et se désactive dans l'impression. Si le rapport indique qu'une cible n'est pas confirmée visuellement pour ce type d'arrière-plan, dites-le brièvement.
Ajustement ultérieur
- "Trop" ou "je ne le vois pas" : déplacez d'un niveau.
-
…
[version tronquée pour la traduction]