You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建带噪点纹理的黑到透明SCSS渐变?消除生硬边界

问题描述

在Stack Overflow找到一篇关于创建噪点渐变的旧帖子,但实现效果无法平滑过渡到透明,会产生生硬边界。需求是仅让渐变部分带有噪点,完全透明的区域不带噪点。

当前尝试的代码如下:

CSS代码

.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噪点代码

<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>

问题现象:渐变到透明的边界处噪点依然存在,形成生硬的边缘。
期望效果:噪点随渐变的不透明度同步衰减,完全透明区域无噪点(类似Photoshop制作的平滑噪点渐变)。


解决方案1:CSS背景混合模式实现

核心是通过background-blend-mode让噪点仅在渐变不透明区域显示,修改CSS代码如下:

.black-bar {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100px;
    background-size: cover;
    background-position: center;
    background-repeat: repeat;
    /* 调整背景层顺序:噪点在前,渐变在后 */
    background-image: url('/noise.svg'),
            linear-gradient(to bottom,
            rgba(0, 0, 0, 1) 0%,
            rgba(0, 0, 0, 1) 50%,
            rgba(0, 0, 0, 0) 100%);
    /* 用multiply混合模式让渐变作为噪点的遮罩 */
    background-blend-mode: multiply;
    z-index: -1;  
}

原理:multiply混合模式会将两层颜色相乘,渐变的透明区域(alpha=0)会完全消除下方的噪点,不透明区域则保留噪点与黑色渐变的混合效果,实现平滑过渡。


解决方案2:SVG内部集成渐变遮罩

如果希望将效果封装在SVG中,可修改SVG代码,用渐变遮罩控制噪点显示范围:

<svg viewBox='0 0 250 250' xmlns='http://www.w3.org/2000/svg'>
  <defs>
    <!-- 定义与需求匹配的渐变遮罩 -->
    <linearGradient id="fadeGradient" x1="0%" y1="0%" x2="0%" y2="100%">
      <stop offset="0%" stop-color="white" stop-opacity="1"/>
      <stop offset="50%" stop-color="white" stop-opacity="1"/>
      <stop offset="100%" stop-color="white" stop-opacity="0"/>
    </linearGradient>
    <mask id="fadeMask">
      <rect width="100%" height="100%" fill="url(#fadeGradient)"/>
    </mask>
    
    <!-- 噪点滤镜 -->
    <filter id='noiseFilter'>
      <feTurbulence 
        type='fractalNoise' 
        baseFrequency='5' 
        numOctaves='3' 
        stitchTiles='stitch'/>
    </filter>
  </defs>
  
  <!-- 用遮罩包裹噪点矩形,仅显示渐变范围内的噪点 -->
  <rect width='100%' height='100%' filter='url(#noiseFilter)' mask="url(#fadeMask)" fill="black"/>
</svg>

对应的CSS可简化为直接引用该SVG:

.black-bar {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100px;
    background-size: cover;
    background-position: center;
    background-repeat: repeat;
    background-image: url('/noise-with-fade.svg');
    z-index: -1;  
}

原理:SVG内部通过mask元素,用渐变控制噪点矩形的显示区域,导出的SVG本身就具备平滑的噪点渐变效果,无需额外CSS混合处理。


内容的提问来源于stack exchange,提问作者Rasmus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:35:56