skip to Main Content

I found this old thread on how to create noise gradients, but it doesn’t properly fade to transparent which creates a hard border effect. I was wondering if it was possible to have only the gradient be noisy, not the transparency in the end.

Here is what I tried so far:

.black-bar {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100px;
    background-size: cover;
    background-position: center;
    background-repeat: repeat;
    stop-color: black;
    background-image: linear-gradient(to bottom,
            rgba(0, 0, 0, 1) 0%,
            rgba(0, 0, 0, 1) 50%,
            rgba(0, 0, 0, 0) 100%),
            url('/noise.svg');
    z-index: -1;  
}
<svg viewBox='0 0 250 250' xmlns='http://www.w3.org/2000/svg'>
  <filter id='noiseFilter'>
    <feTurbulence 
      type='fractalNoise' 
      baseFrequency='5' 
      numOctaves='3' 
      stitchTiles='stitch'/>
  </filter>
  
  <rect width='100%' height='100%' filter='url(#noiseFilter)'/>
</svg>

And here is the border effect I’m talking about:

Hard border effect I don’t want

Noisy gradient I’m looking for (Mockup created in Photoshop)

2

Answers


  1. Chosen as BEST ANSWER

    I found the solution. Inverting the noise while fading itself to transparent while applying it after the gradient seemed to create the transition I'm looking for. Here is the scss

    .black-bar {
        position: absolute;
        width: 100%;
        height: 300px;
        background: linear-gradient(180deg, 
            rgba(0,0,0,1) 0%,
            rgba(0,0,0,1) 20%,
            rgba(0, 0, 0, 0) 100%);
        z-index: 1;
    }
    
    .black-bar::after {
        content: '';
        position: absolute; 
        width: 100%;
        height: 100%;
        background: url('/noise.svg');
        filter: contrast(200%) brightness(100%) invert(100%) saturate(0%);
        mask-image: linear-gradient(180deg, 
            rgba(0,0,0,0) 0%,
            rgba(0,0,0,.3) 40%,
            rgba(0,0,0,0) 100%);
        z-index: -1;
    }
    

    And here is the final result


  2. I don’t get the requirements 100%, but is it something like this. The SVG has a rectangle with both a filter and a mask. The mask creates the gradient. Therefore the noise filter is not visible in the transparent part of the rectangle. The part I don’t get is the black color. Should the gradient cover the black?

    .black-bar {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100px;
      background-size: contain;
      background-position: center;
      background-repeat: repeat;
      background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZGVmcz4KICA8ZmlsdGVyIGlkPSJub2lzZUZpbHRlciI+CiAgICA8ZmVUdXJidWxlbmNlIAogICAgICB0eXBlPSJmcmFjdGFsTm9pc2UiCiAgICAgIGJhc2VGcmVxdWVuY3k9Ii40IiAKICAgICAgbnVtT2N0YXZlcz0iLjQiIAogICAgICBzdGl0Y2hUaWxlcz0ic3RpdGNoIiAvPgogIDwvZmlsdGVyPgogIDxsaW5lYXJHcmFkaWVudCBpZD0ibGcwMSIgZ3JhZGllbnRUcmFuc2Zvcm09InJvdGF0ZSg5MCkiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1vcGFjaXR5PSIxIiBzdG9wLWNvbG9yPSJ3aGl0ZSIgLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1vcGFjaXR5PSIwIiBzdG9wLWNvbG9yPSJ3aGl0ZSIgLz4KICA8L2xpbmVhckdyYWRpZW50PgogIDxtYXNrIGlkPSJtMDEiPgogICAgPHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNsZzAxKSIvPgogIDwvbWFzaz4KICA8L2RlZnM+CiAgPHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgbWFzaz0idXJsKCNtMDEpIiBmaWx0ZXI9InVybCgjbm9pc2VGaWx0ZXIpIi8+Cjwvc3ZnPg==');
      z-index: -1;
    }
    <div class="black-bar"></div>
    
    <p>The SVG used as background image:</p>
    <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
      <defs>
      <filter id="noiseFilter">
        <feTurbulence 
          type="fractalNoise"
          baseFrequency=".4" 
          numOctaves=".4" 
          stitchTiles="stitch" />
      </filter>
      <linearGradient id="lg01" gradientTransform="rotate(90)">
        <stop offset="0%" stop-opacity="1" stop-color="white" />
        <stop offset="100%" stop-opacity="0" stop-color="white" />
      </linearGradient>
      <mask id="m01">
        <rect width="100%" height="100%" fill="url(#lg01)"/>
      </mask>
      </defs>
      <rect width="100%" height="100%" mask="url(#m01)" filter="url(#noiseFilter)"/>
    </svg>

    Second attempt

    Maybe this is more like it. The filter is now part of the mask. And the mask is going from white to black with a opaque (.5) part in the middle. The opaque part will make the filter visible. The mask is applied to a black rectangle making the top black and the bottom transparent.

    I made a SVG for the content of the page, so it looks more like your mock-up.

    This is the SVG that is used at a background image in the CSS:

    <?xml version="1.0" encoding="utf-8"?>
    <svg width="10000" height="400" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <filter id="noiseFilter">
          <feTurbulence type="fractalNoise"
            stitchTiles="stitch"
            numOctaves="4"
            baseFrequency=".2"
            result="turbulence" />
          <feDisplacementMap
            in="turbulence"
            scale="2000" />
        </filter>
        <linearGradient id="lg01" gradientTransform="rotate(90)">
          <stop offset="0%" stop-opacity="1" stop-color="white" />
          <stop offset="20%" stop-opacity="1" stop-color="white" />
          <stop offset="60%" stop-opacity=".5" stop-color="black" />
          <stop offset="90%" stop-opacity="1" stop-color="black" />
        </linearGradient>
        <mask id="m01">
          <rect width="100%" height="100%" filter="url(#noiseFilter)"/>
          <rect width="100%" height="100%" fill="url(#lg01)" />
        </mask>
      </defs>
      <rect width="100%" height="100%" mask="url(#m01)" fill="black"/>
    </svg>
    
    body {
      background-color: #a2d6e9;
    }
    
    .black-bar {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 400px;
      background-repeat: repeat-x;
      background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTAwMDAiIGhlaWdodD0iNDAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxkZWZzPgogICAgPGZpbHRlciBpZD0ibm9pc2VGaWx0ZXIiPgogICAgICA8ZmVUdXJidWxlbmNlIHR5cGU9ImZyYWN0YWxOb2lzZSIKICAgICAgICBzdGl0Y2hUaWxlcz0ic3RpdGNoIgogICAgICAgIG51bU9jdGF2ZXM9IjQiCiAgICAgICAgYmFzZUZyZXF1ZW5jeT0iLjIiCiAgICAgICAgcmVzdWx0PSJ0dXJidWxlbmNlIiAvPgogICAgICA8ZmVEaXNwbGFjZW1lbnRNYXAKICAgICAgICBpbj0idHVyYnVsZW5jZSIKICAgICAgICBzY2FsZT0iMjAwMCIgLz4KICAgIDwvZmlsdGVyPgogICAgPGxpbmVhckdyYWRpZW50IGlkPSJsZzAxIiBncmFkaWVudFRyYW5zZm9ybT0icm90YXRlKDkwKSI+CiAgICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0b3Atb3BhY2l0eT0iMSIgc3RvcC1jb2xvcj0id2hpdGUiIC8+CiAgICAgIDxzdG9wIG9mZnNldD0iMjAlIiBzdG9wLW9wYWNpdHk9IjEiIHN0b3AtY29sb3I9IndoaXRlIiAvPgogICAgICA8c3RvcCBvZmZzZXQ9IjYwJSIgc3RvcC1vcGFjaXR5PSIuNSIgc3RvcC1jb2xvcj0iYmxhY2siIC8+CiAgICAgIDxzdG9wIG9mZnNldD0iOTAlIiBzdG9wLW9wYWNpdHk9IjEiIHN0b3AtY29sb3I9ImJsYWNrIiAvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICAgIDxtYXNrIGlkPSJtMDEiPgogICAgICA8cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWx0ZXI9InVybCgjbm9pc2VGaWx0ZXIpIi8+CiAgICAgIDxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjbGcwMSkiIC8+CiAgICA8L21hc2s+CiAgPC9kZWZzPgogIDxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIG1hc2s9InVybCgjbTAxKSIgZmlsbD0iYmxhY2siLz4KPC9zdmc+');
      z-index: 1;
    }
    <div class="black-bar"></div>
    <svg viewBox="0 0 100 50" height="400" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <linearGradient id="lg01" gradientTransform="rotate(90)">
          <stop offset="0%" stop-opacity="0" stop-color="black" />
          <stop offset="80%" stop-opacity="1" stop-color="black" />
        </linearGradient>
        <mask id="m01">
          <circle cx="20" cy="25" r="15" fill="white"/>
          <circle cx="40" cy="35" r="15" fill="white"/>
          <rect width="100" height="50" fill="url(#lg01)" />
          <path d="M 0 0 L -0.5 30 c 0 2 1 2 1 0 Z" transform="translate(10 -10)" fill="white" opacity=".8" />
          <path d="M 0 0 L -0.5 30 c 0 2 1 2 1 0 Z" transform="translate(20 0)" fill="white" opacity=".8" />
          <path d="M 0 0 L -0.5 30 c 0 2 1 2 1 0 Z" transform="translate(30 10)" fill="white" opacity=".8" />
          <path d="M 0 0 L -0.5 30 c 0 2 1 2 1 0 Z" transform="translate(80 10)" fill="white" opacity=".8" />
        </mask>
      </defs>
      <rect width="100" height="50" fill="white" mask="url(#m01)" />
    </svg>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search