Film Noir
Texture pellicule pure CSS : grain feTurbulence animé en steps, scanlines horizontales et vignette radiale sombre — aucune dépendance, aucun JS.
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. Backgrounds comprend 50 effets, dont 6 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
L'effet est une pile de quatre couches position: absolute; inset: 0 sur un conteneur .ng-film-scene. La couche clé est .ng-film-grain, un <div> vide dont le style inline porte filter: url(#ng-film-filter). Un filtre SVG <feTurbulence type="fractalNoise" baseFrequency="0.65" numOctaves="3" stitchTiles="stitch"> — à définir une fois dans la page — génère une carte de bruit fractale (bruit de Perlin). Un <feColorMatrix> convertit le bruit en blanc semi-transparent ; superposé à opacity: 0.4, il produit la texture de grain argentique.
L'animation @keyframes ngFilmFlicker (0,1 s, steps(3)) translate .ng-film-grain sans interpolation entre trois positions : (0,0), (−2 px, 1 px), (1 px, −1 px). steps(3) garantit des sauts secs — le grain semble recalculé à chaque image alors que la carte SVG reste statique, car c'est la fenêtre de découpe qui se déplace. À 0,1 s × 3 positions, le grain change à ≈ 30 images/s, imitant les pellicules 24–30 images.
Les scanlines sont un repeating-linear-gradient(0deg, transparent 2px, rgba(0,0,0,0.05) 4px) sur .ng-film-lines — densité 4 px, opacité 0,05. La vignette est un radial-gradient(transparent 50%, rgba(0,0,0,0.6) 100%) sur .ng-film-vignette, qui assombrit les bords sans toucher au centre.
Aucun JavaScript n'est impliqué — l'effet est 100 % CSS + SVG. La couche .ng-film-gradient (deux gradients radiaux colorés) est entièrement facultative : remplacez ses couleurs ou supprimez-la pour changer l'ambiance chromatique sans toucher au grain.
Accessibilité
- Aucun bloc
@media (prefers-reduced-motion: reduce)n'est présent dans le code fourni : l'animationngFilmFlickertourne en continu. Pour les utilisateurs sensibles au mouvement, ajoutez.ng-film-grain { animation: none; }dans ce media-query. - L'effet est purement décoratif : ajoutez
role="img"et unaria-labeldescriptif sur.ng-film-scenesi le bloc porte un sens visuel, sinon marquez-learia-hidden="true". - La vignette assombrit les bords mais épargne le centre : un titre blanc centré sur fond
#1a1a2eatteint un ratio de contraste ≈ 13:1 (WCAG AA validé). - Pas de JavaScript, pas d'interaction — aucune problématique de navigation au clavier liée à l'effet lui-même.
- Sans support SVG Filters (environnements très anciens),
.ng-film-grains'affiche transparent ; les scanlines et la vignette CSS restent actives — dégradé gracieux sans erreur.
Compatibilité navigateur
Nécessite SVG Filters (feTurbulence) et CSS animations — supportés dans tous les navigateurs modernes depuis 2016. Zéro dépendance externe, aucun JS.
Sans support SVG Filters, <code>.ng-film-grain</code> s'affiche vide (filtre ignoré) ; les scanlines et la vignette CSS restent actives. Aucune erreur JS.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="ng-film-scene" role="img" aria-label="Texture pellicule animée — grain, scanlines, vignette">
<!-- Filtre SVG (une seule fois par page) -->
<svg style="display:none" aria-hidden="true">
<filter id="ng-film-filter">
<feTurbulence type="fractalNoise" baseFrequency="0.65" numOctaves="3" stitchTiles="stitch"/>
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.3 0.3 0.3 0 0"/>
</filter>
</svg>
<div class="ng-film-gradient" aria-hidden="true"></div>
<div class="ng-film-grain" style="filter: url(#ng-film-filter)" aria-hidden="true"></div>
<div class="ng-film-lines" aria-hidden="true"></div>
<div class="ng-film-vignette" aria-hidden="true"></div>
<!-- Votre contenu overlay (position: relative; z-index: 2) -->
<div class="ng-film-content">…</div>
</div>
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éfaut | Effet |
|---|---|---|
| .ng-film-grain — opacity: 0.4 | 0.4 | Intensité du grain. 0,2 = pellicule neuve subtile, 0,6 = film 16 mm usé. |
| .ng-film-grain — animation-duration: 0.1s | 0.1s | Vitesse de clignotement. 0,05 s = très rapide (super 8), 0,2 s = lent (ambiance onirique). |
| .ng-film-grain — steps(3) | 3 | Nombre de positions de grain par cycle. 2 = très saccadé, 6 = transitions plus douces. |
| .ng-film-vignette — rgba(0,0,0,.6) dans radial-gradient | 0.6 | Intensité de la vignette. 0,3 = subtile, 0,85 = encadrement ciné plein écran. |
| .ng-film-vignette — transparent 50% | 50% | Étendue de la zone centrale non assombrie. 30 % = vignette serrée (portrait), 70 % = bords effleurés seulement. |
| .ng-film-lines — rgba(0,0,0,.05) dans repeating-linear-gradient | 0.05 | Opacité des scanlines. 0 = invisibles, 0,15 = marquées (vieux moniteur CRT). |
| .ng-film-lines — pitch 4px dans repeating-linear-gradient | 4px | Densité des lignes. 4 px = TV définition standard, 2 px = haute densité, 6 px = grossier années 70. |
| .ng-film-scene — background: #1a1a2e | #1a1a2e | Couleur de fond du conteneur. Remplacez par votre teinte : noir pur, sépia, bleu nuit, bordeaux. |
FAQ
<svg style="display:none"><filter id="ng-film-filter"><feTurbulence type="fractalNoise" baseFrequency="0.65" numOctaves="3" stitchTiles="stitch"/><feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.3 0.3 0.3 0 0"/></filter></svg>. Sur une page multi-scènes, une seule définition suffit pour toutes les instances.position: absolute. Ajoutez votre contenu dans un <div> avec position: relative; z-index: 2 à l'intérieur de .ng-film-scene. La vignette assombrit les bords — placez votre texte au centre pour un contraste optimal.@keyframes ne s'arrêtent pas hors du viewport. Pour économiser du CPU sur mobile, ajoutez un IntersectionObserver JS qui bascule animation-play-state: paused sur .ng-film-grain quand la scène sort de l'écran, et running quand elle revient.