I saw a website that had elements on it that had some gradients that had a noise effect applied to them. They were just images, but it got me wondering if noise is possible in just CSS. Turns out that it is, with a little help from svg filters. I found this technique on this css tricks article and modified it to suit my needs.
How this works
SVG filters can do some unique things that you can't do with a CSS filter. In particular, there is a filter named turbulence that lets you layer noise over top of your svg. If you apply that filter to a plain rectangle, you get an SVG that is just noise that you can use as a background image. In addition to the noise, I've also applied a saturation filter to remove the color from the noise and make it greyscale, and then an alpha filter to drop the opacity, both of which make it so it layers over everything easily.
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<filter id="noiseFilter">
<feTurbulence type="fractalNoise" baseFrequency="0.95" numOctaves="3" stitchTiles="stitch" />
<feColorMatrix type="saturate" values="0"/>
<feComponentTransfer>
<feFuncA type="linear" slope="0.15"/>
</feComponentTransfer>
</filter>
<rect width="100%" height="100%" filter="url(%23noiseFilter)" />
</svg>
To use this in our CSS, we can url encode it and use it as a data: url, and then layer it over top a gradient in a background.
.gradient {
--noise: url('data:image/svg+xml,<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"><filter id="noiseFilter"><feTurbulence type="fractalNoise" baseFrequency="0.95" numOctaves="3" stitchTiles="stitch" /><feColorMatrix type="saturate" values="0"/><feComponentTransfer><feFuncA type="linear" slope="0.15"/></feComponentTransfer></filter><rect width="100%" height="100%" filter="url(%23noiseFilter)" /></svg>');
--gradient: linear-gradient(to bottom right, rgb(42, 123, 155) 0%, rgb(152, 87, 199) 50%, rgb(237, 83, 224) 100%);
background: var(--noise), var(--gradient);
}
Playground
I threw together this playground that lets you fine tune your own noise values.
CSS
.gradient {
--noise: url('data:image/svg+xml,<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"><filter id="noiseFilter"><feTurbulence type="fractalNoise" baseFrequency="0.95" numOctaves="3" stitchTiles="stitch" /><feColorMatrix type="saturate" values="0"/><feComponentTransfer><feFuncA type="linear" slope="0.15"/></feComponentTransfer></filter><rect width="100%" height="100%" filter="url(%23noiseFilter)" /></svg>');
--gradient: linear-gradient(to top left, #5ee7df 0%,#b490ca 100%);
background: var(--noise), var(--gradient);
}