Soft pastel color clouds drift across warm paper while a fine grain shimmers on top, the printed gradient look of modern brand sites. SVG turbulence grain multiplies over blurred radial clouds.
Also known as: noise gradient background css, grainy gradient light, noise grain gradient, risograph gradient background.
<div class="bgx-paper-grain" aria-hidden="true"><span></span><span></span><span></span></div>
.bgx-paper-grain {
--c: var(--bgx-color, #3b82f6);
font-size: var(--bgx-size, 16px);
position: absolute;
inset: 0;
overflow: hidden;
background: oklch(from var(--c) 0.97 0.015 calc(h + 40));
isolation: isolate;}
.bgx-paper-grain span {
position: absolute;
left: var(--x);
top: var(--y);
width: var(--w);
aspect-ratio: 1.4;
translate: -50% -50%;
background: radial-gradient(closest-side, var(--a), transparent);
animation: bgx-paper-grain-drift var(--t) cubic-bezier(0.45, 0, 0.55, 1) var(--d) infinite alternate;
}
.bgx-paper-grain span:nth-child(1) { --x: 25%; --y: 35%; --w: max(70%, 22em); --t: 12s; --d: -3s; --a: oklch(from var(--c) 0.8 0.14 calc(h + 0)); }
.bgx-paper-grain span:nth-child(2) { --x: 75%; --y: 30%; --w: max(60%, 19em); --t: 14s; --d: -8s; --a: oklch(from var(--c) 0.85 0.12 calc(h + 70)); }
.bgx-paper-grain span:nth-child(3) { --x: 60%; --y: 85%; --w: max(75%, 24em); --t: 10s; --d: -5s; --a: oklch(from var(--c) 0.82 0.12 calc(h - 70)); }
.bgx-paper-grain::after {
content: "";
position: absolute;
inset: -5em;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200' preserveAspectRatio='none'%3E%3Cfilter id='n' x='0' y='0' width='100%' height='100%'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.1 0 0 0 0 0.08 0 0 0 0 0.06 0 0 0 1.3 -0.55'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E") 0 0 / 10em 10em;
mix-blend-mode: multiply;
opacity: 0.32;
animation: bgx-paper-grain-jitter 0.9s steps(1) infinite;
}
@keyframes bgx-paper-grain-drift {
from { transform: translate(-10%, 6%) scale(0.9); }
to { transform: translate(10%, -6%) scale(1.12); }
}
@keyframes bgx-paper-grain-jitter {
0% { transform: translate(0, 0); }
25% { transform: translate(-3em, 2em); }
50% { transform: translate(2em, -4em); }
75% { transform: translate(-1em, -2em); }
}
@media (prefers-reduced-motion: reduce) {
.bgx-paper-grain, .bgx-paper-grain::before, .bgx-paper-grain::after, .bgx-paper-grain *, .bgx-paper-grain *::before, .bgx-paper-grain *::after { animation-play-state: paused; }
}
@media (prefers-reduced-motion: reduce) {
.bgx-paper-grain, .bgx-paper-grain *, .bgx-paper-grain::before, .bgx-paper-grain::after, .bgx-paper-grain *::before, .bgx-paper-grain *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--bgx-color on the element or a parent.
Currently previewing #3b82f6.--bgx-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 16px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.