Can you add noise to a CSS3 gradient?

CssGradient

Css Problem Overview


Is it possible to add noise to a gradient in CSS?

Here is my code for a radial gradient:

body {
    color: #575757;
    font: 14px/21px Arial, Helvetica, sans-serif;
    background-color: #2f3b4b;
    background: -moz-radial-gradient(center 45deg, circle closest-corner, #2f3b4b 0%, #3e4f63 100%);
    background: -webkit-gradient(radial, center center, 10, center center, 900, from(#2f3b4b), to(#3e4f63));
}

What would I add to that to have noise on top of it, to give it texture?

Css Solutions


Solution 1 - Css

This is by far the most hassle free and best way to implement this. It is purely CSS and very very simple to do, no extra files - nothing. Ok, it's not the best way possible, but it works very well, very reliable (never failed when testing across very old browsers) and very fast to load.

Found it a few months ago, and used it ever since, simply copy and paste this code in to your CSS.

background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAUVBMVEWFhYWDg4N3d3dtbW17e3t1dXWBgYGHh4d5eXlzc3OLi4ubm5uVlZWPj4+NjY19fX2JiYl/f39ra2uRkZGZmZlpaWmXl5dvb29xcXGTk5NnZ2c8TV1mAAAAG3RSTlNAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAvEOwtAAAFVklEQVR4XpWWB67c2BUFb3g557T/hRo9/WUMZHlgr4Bg8Z4qQgQJlHI4A8SzFVrapvmTF9O7dmYRFZ60YiBhJRCgh1FYhiLAmdvX0CzTOpNE77ME0Zty/nWWzchDtiqrmQDeuv3powQ5ta2eN0FY0InkqDD73lT9c9lEzwUNqgFHs9VQce3TVClFCQrSTfOiYkVJQBmpbq2L6iZavPnAPcoU0dSw0SUTqz/GtrGuXfbyyBniKykOWQWGqwwMA7QiYAxi+IlPdqo+hYHnUt5ZPfnsHJyNiDtnpJyayNBkF6cWoYGAMY92U2hXHF/C1M8uP/ZtYdiuj26UdAdQQSXQErwSOMzt/XWRWAz5GuSBIkwG1H3FabJ2OsUOUhGC6tK4EMtJO0ttC6IBD3kM0ve0tJwMdSfjZo+EEISaeTr9P3wYrGjXqyC1krcKdhMpxEnt5JetoulscpyzhXN5FRpuPHvbeQaKxFAEB6EN+cYN6xD7RYGpXpNndMmZgM5Dcs3YSNFDHUo2LGfZuukSWyUYirJAdYbF3MfqEKmjM+I2EfhA94iG3L7uKrR+GdWD73ydlIB+6hgref1QTlmgmbM3/LeX5GI1Ux1RWpgxpLuZ2+I+IjzZ8wqE4nilvQdkUdfhzI5QDWy+kw5Wgg2pGpeEVeCCA7b85BO3F9DzxB3cdqvBzWcmzbyMiqhzuYqtHRVG2y4x+KOlnyqla8AoWWpuBoYRxzXrfKuILl6SfiWCbjxoZJUaCBj1CjH7GIaDbc9kqBY3W/Rgjda1iqQcOJu2WW+76pZC9QG7M00dffe9hNnseupFL53r8F7YHSwJWUKP2q+k7RdsxyOB11n0xtOvnW4irMMFNV4H0uqwS5ExsmP9AxbDTc9JwgneAT5vTiUSm1E7BSflSt3bfa1tv8Di3R8n3Af7MNWzs49hmauE2wP+ttrq+AsWpFG2awvsuOqbipWHgtuvuaAE+A1Z/7gC9hesnr+7wqCwG8c5yAg3AL1fm8T9AZtp/bbJGwl1pNrE7RuOX7PeMRUERVaPpEs+yqeoSmuOlokqw49pgomjLeh7icHNlG19yjs6XXOMedYm5xH2YxpV2tc0Ro2jJfxC50ApuxGob7lMsxfTbeUv07TyYxpeLucEH1gNd4IKH2LAg5TdVhlCafZvpskfncCfx8pOhJzd76bJWeYFnFciwcYfubRc12Ip/ppIhA1/mSZ/RxjFDrJC5xifFjJpY2Xl5zXdguFqYyTR1zSp1Y9p+tktDYYSNflcxI0iyO4TPBdlRcpeqjK/piF5bklq77VSEaA+z8qmJTFzIWiitbnzR794USKBUaT0NTEsVjZqLaFVqJoPN9ODG70IPbfBHKK+/q/AWR0tJzYHRULOa4MP+W/HfGadZUbfw177G7j/OGbIs8TahLyynl4X4RinF793Oz+BU0saXtUHrVBFT/DnA3ctNPoGbs4hRIjTok8i+algT1lTHi4SxFvONKNrgQFAq2/gFnWMXgwffgYMJpiKYkmW3tTg3ZQ9Jq+f8XN+A5eeUKHWvJWJ2sgJ1Sop+wwhqFVijqWaJhwtD8MNlSBeWNNWTa5Z5kPZw5+LbVT99wqTdx29lMUH4OIG/D86ruKEauBjvH5xy6um/Sfj7ei6UUVk4AIl3MyD4MSSTOFgSwsH/QJWaQ5as7ZcmgBZkzjjU1UrQ74ci1gWBCSGHtuV1H2mhSnO3Wp/3fEV5a+4wz//6qy8JxjZsmxxy5+4w9CDNJY09T072iKG0EnOS0arEYgXqYnXcYHwjTtUNAcMelOd4xpkoqiTYICWFq0JSiPfPDQdnt+4/wuqcXY47QILbgAAAABJRU5ErkJggg==);

Then add your background color

background-color:#0094d0;

Demo: JSFiddle

Source: https://coderwall.com/p/m-uwvg

Solution 2 - Css

There's no current way in css to add 'noise' to a background.

An alternative solution would be to create a transparent noise png in your graphic editor. Then apply that graphic as a background to a <div>. You would then need to place that <div> over the entire area of the <body> which should then give an appearance of a gradient with noise.

Solution 3 - Css

Creating Textures (Noise) Using SVG Filters & CSS Gradients

You want noise in your gradient? You're in luck!

Perlin noise is a type of gradient noise. The SVG standard specifies a filter primitive called <feTurbulence>, which implements the Perlin function. It allows the synthesis of artificial textures like clouds or marble—the noise you want.

Step 1: Define an SVG Graphic

Create a small SVG file called noise.svg.

<svg
  xmlns='http://www.w3.org/2000/svg'
  xmlns:xlink='http://www.w3.org/1999/xlink'
  width='300' height='300'>

    <filter id='n' x='0' y='0'>
            <feTurbulence
              type='fractalNoise'
              baseFrequency='0.75'
              stitchTiles='stitch'/>
    </filter>

    <rect width='300' height='300' fill='#fff'/>
    <rect width='300' height='300' filter="url(#n)" opacity='0.80'/>
</svg>

This graphic defines two rectangles. The first is filled with a solid color. The second is translucent with the noise filter applied. The second rectangle is overlayed on the first to provide a noise effect.

SVG Options
  1. Fist and most obvious is that you can change the dimensions of the graphic. However, the CSS background-repeat property can be used to fill an element, thus 300×300 should suffice.

  2. The filter's type attribute can be fractalNoise or turbulence, which specifies the filter function. Both provide a different visual, but in my opinion, the noise filter is a little more subtle.

  3. The filter's baseFrequency attribute can range from 0.5–0.9 to provide a course to fine texture, respectively. This range is visually optimal for either filter in my opinion.

  4. The first rectangle's fill can be changed to provide a different base color. Later, however, we essentially combine this color with a translucent CSS gradient, which also defines a color(s). So white is a good starting point here.

  5. The second rectangle's opacity can range from 0.2–0.9 to set the filter intensity, where a higher number increases the intensity.

At this point, you could tweak the aforementioned options, set this noise graphic as a background image via CSS, and call it a day. But if you want a gradient, like the OP, go to Step 2.

Step 2: Apply a CSS Gradient

Using the background-image property, you can set the SVG noise graphic as the background on any element and overlay a gradient. In this example, I'll apply the noise graphic to the entire body and overlay a linear gradient.

body {
    /* white to black linear noise gradient spanning from top to bottom */
    background:
      linear-gradient(rgba(255,255,255,.5), rgba(0,0,0,.5)),
      url('noise.svg');
}

The linear-gradient() function creates a pseudo image, which is stacked on top of noise.svg. The result is a translucent gradient with our noise showing through it.

CSS Options
  1. First, and most obvious, is that the defined gradient colors can be changed. However, if you want a solid color without a gradient, make the two end-point colors equal. The benefit is that you can use the same noise graphic with or without a gradient throughout a site or among projects.

  2. Multiple images, created with the *-gradient() functions, can be overlayed on the noise graphic and more than two color parameters and angles can be specified in a single gradient function to provide all kinds of cool visuals.

  3. The opacity of the gradient parameters—i.e. rgba() and hsla()—can be increased to intensify the defined color and reduce the noise level. Again, 0.2–0.9 is an ideal range.

Conclusion

This is a highly customizable and very light-weight (~400 bytes) solution that allows you to simply define noise of any color or gradient. Although there are several knobs to turn here, this is only the beginning. There are other SVG filter primitives, such as <feGaussianBlur> and <feColorMatrix>, which can provide additional results.

Solution 4 - Css

For the sake of novelty, here is some pure CSS noise without using a data URI:

#box {
  width:250px;
  height:250px;
  position:relative;
  background-size:55px 10px;
  background-repeat: repeat;
  background-image: -webkit-repeating-radial-gradient(1% 21%, closest-corner, rgba(255,0,255,.5), rgba(0,255,255,.5), rgba(0,0,0,1) 1.7%), -webkit-repeating-radial-gradient(51% 51%, closest-corner, rgba(255,255,255,1), rgba(255,255,255,1), rgba(0,255,0,1) 10%); 
}
#box::before {
  content:'';
  width:100%;
  height:100%;
  position:absolute;
  mix-blend-mode:exclusion;
  background-size:12px 22px;
  background-repeat: repeat;
  background-image: -webkit-repeating-radial-gradient(61% 21%, closest-corner, rgba(255,255,255,1), rgba(0,255,0,.5), rgba(3,0,255,1) 20%),  -webkit-repeating-radial-gradient(91% 51%, closest-corner, rgba(255,255,255,1), rgba(255,255,1,.5), rgba(055,255,255,1) 20%);
  left:0;
  z-index:998;
}
#box::after {
  content:'';
  width:100%;
  height:100%;
  position:absolute;
  mix-blend-mode:exclusion;
  background-size:15px 13px;
  background-repeat: repeat;
  background-image: -webkit-repeating-radial-gradient(21% 21%, closest-corner, rgba(255,255,255,1), rgba(0,0,255,.5), rgba(3,0,255,1) 20%);
  left:0;
  top:0;
  z-index:999;
}

<div id="box"></div>

Some more information about how this was created: http://jollo.org/LNT/public/css-noise.html

Solution 5 - Css

While this doesn't qualify as true noise, a pure CSS3 approach would be using multiple repeating-linear-background selectors, which are often used in pattern generators.

Here are a few examples:

With some right combination of backgrounds, angles, color stops, and transparency, a reasonable noise-like effect should be achievable :)

Hope that sets you in the right direction anyways...

Solution 6 - Css

Yes, there's currently no CSS-based approach for noise textures. If you're hell-bent on a programmatic (rather than image-based) approach, though, you could try using HTML5 canvas. There's a tutorial here on how to generate noise using JavaScript --> Creating Noise in HTML5 Canvas

However, doing the Canvas approach will result in a much slower experience for your visitors, because A) JavaScript is an interpreted language, and B) writing graphics using JS is extra slow.

So, unless you're trying to make a point by using HTML5, I'd stick with an image. It'll be faster (for you to make and for your users to load), and you'll have a finer degree of control over the appearance.

Solution 7 - Css

It is not possible (even if it was, it'd take a crapton of code tricks to do so) to generate noise textures using CSS alone. There aren't any new CSS3 properties that provide that sort of effect out of the box. A much quicker solution is to use a graphic editor such as Photoshop to do that.

Solution 8 - Css

Building on top of Clint Pachl's answer, I used CSS's mix-blend-mode to get a grainier effect and to selectively punch up the colors of that make up the gradient.

See https://jsfiddle.net/jimmmy/2ytzh30w/ for example code.

Update: I wrote an article about it in CSS-Tricks: Grainy Gradients

Noise using css

Solution 9 - Css

I found a way without any image with radial-gradient and only one div.

Firstly I want to show an example with radial-gradient. Let's say we want to create a circle at coordinates we want. First circle is x=120 y=80, second circle is x=20 y=20. To better understand the function we will write below, we can consider this example.

.a {
border:1px solid blue;
  width:500px;
  height:200px;
  background: radial-gradient(circle at 120px 80px, red 0px 10px, transparent 10px 100px);
}

.b {
border:1px solid red;
  width:500px;
  height:200px;
  background: radial-gradient(circle at 20px 20px, blue 0px 10px, transparent 10px 100px);
}

<div class="a"></div>
<div class="b"></div>

We are going to write a @mixin function for thousands line gradients.

A SCSS function:

@mixin gradient($color, $width, $height, $noiseCount) {
  $value: ();
  @for $i from 1 through $noiseCount {
    $gradient: radial-gradient(
      circle at #{random($width)}px #{random($height)}px,
      $color 0px,
      $color 1px,
      transparent 1px,
      transparent 100%
    );
    $value: append($value, $gradient, comma);
  }
  background: $value;
}

Usage:

div {
  width:400px;
  height: 150px;
  @include gradient(#ffad3e, 400, 150, 2500);
}

Result

If we want to create noises according to % value?

We can use this function for this.

@mixin gradient($color, $width, $height, $noiseCount) {
  $value: ();
  @for $i from 1 through $noiseCount {
    $gradient: radial-gradient(
      circle at #{(random($width * 10)) / 10}% #{random($height)}px,
      $color 0px,
      $color 1px,
      transparent 1px,
      transparent 100%
    );
    $value: append($value, $gradient, comma);
  }
  background: $value;
}

div {
  width:100%;
  height: 150px;
  @include gradient(#ffad3e, 100, 150, 2500);
}

Result

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionaustinView Question on Stackoverflow
Solution 1 - Csstim.bakerView Answer on Stackoverflow
Solution 2 - CssBen RoweView Answer on Stackoverflow
Solution 3 - CssClint PachlView Answer on Stackoverflow
Solution 4 - CssfanfareView Answer on Stackoverflow
Solution 5 - CssAndrew OdriView Answer on Stackoverflow
Solution 6 - CssderrylwcView Answer on Stackoverflow
Solution 7 - CssBoltClockView Answer on Stackoverflow
Solution 8 - CssjimbotronView Answer on Stackoverflow
Solution 9 - CssdoğukanView Answer on Stackoverflow