【问题标题】:Can you add noise to a CSS3 gradient?你能在 CSS3 渐变中添加噪点吗?
【发布时间】:2011-04-29 23:51:24
【问题描述】:

是否可以在 CSS 中为渐变添加噪点?

这是我的径向渐变代码:

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));
}

我会在上面添加什么来增加噪音,赋予它质感?

【问题讨论】:

  • 为什么你没有添加正常的径向渐变?

标签: css gradient


【解决方案1】:

仅使用 CSS 生成噪声纹理是不可能的(即使是这样,也需要大量的代码技巧才能做到这一点)。没有任何新的 CSS3 属性可以提供这种开箱即用的效果。更快的解决方案是使用 Photoshop 等图形编辑器来完成。

【讨论】:

  • 那么您是否建议在 Photoshop 中创建纹理并重复 x 和 y?
  • @austin:是的。您可以单独将噪声创建为重复的透明 PNG 并将其放置为 background-image,或者在图像中包含径向渐变并使其不重复,尽管它更兼容,但您必须保持它的精确尺寸。
【解决方案2】:

目前在 css 中没有向背景添加“噪音”的方法。

另一种解决方案是在您的图形编辑器中创建一个透明的噪声 png。然后将该图形作为背景应用到<div>。然后,您需要将 <div> 放置在 <body> 的整个区域上,这样就会呈现出带有噪点的渐变外观。

【讨论】:

  • 或者使用多个背景图片,最上面的一张是你的噪音PNG。支持渐变的浏览器通常也支持这些。
  • 在我看来,叠加噪声看起来不如真实噪声好。如果使用“乘法”模式混合噪声叠加层会更好,但 CSS 不支持。但是使用带有噪声的巨大梯度图像的替代方法也不是完美的,因为带有噪声的图像压缩得不是很好......
  • 我们可以用过滤器做到这一点吗?
  • 供 2020 年参考,因为这是最佳答案,请参阅下面的答案。
【解决方案3】:

是的,目前没有基于 CSS 的噪声纹理方法。但是,如果您一心想要编程(而不是基于图像)的方法,您可以尝试使用 HTML5 画布。这里有一个关于如何使用 JavaScript 产生噪音的教程 --> Creating Noise in HTML5 Canvas

但是,使用 Canvas 方法会导致访问者的体验变慢,因为 A) JavaScript 是一种解释性语言,并且 B) 使用 JS 编写图形非常慢。

所以,除非您试图通过使用 HTML5 来表达观点,否则我会坚持使用图像。它会更快(您可以制作并让您的用户加载),并且您可以更好地控制外观。

【讨论】:

  • 在某些情况下(尤其是在 HTTP 请求更昂贵的移动设备上)它的运行速度甚至比实际加载还要快!
  • 或者你可以base-64图像。不一定需要 HTTP 请求。
  • 我有一个经过测量的用例,其中带有噪声纹理的图像 80x80 重 10kb,在 base64 之后它将向 css 添加大约 14kb 的文本——这是不可接受的。在 JS 中它是 about 20 lines 的代码,它运行得足够快(并且比通过慢速网络加载这些 14kb 的文本更快)。
  • 绝对是使用 JS 的好理由。虽然 10kb 看起来有点陡峭! 40x40 像素应该为可重复的噪声纹理提供足够的熵,并且小于 2kb。这一切都取决于您的具体情况。
  • 你可以使用 CSS 来做到这一点:/
【解决方案4】:

虽然这不属于真正的噪声,但纯 CSS3 方法将使用多个重复线性背景选择器,这些选择器通常用于模式生成器。

这里有几个例子:

通过适当地组合背景、角度、色标和透明度,应该可以实现合理的类噪点效果 :)

希望无论如何都能让你朝着正确的方向前进......

【讨论】:

    【解决方案5】:

    这是迄今为止最轻松、最好的实现方式。它是纯 CSS 并且非常非常简单,没有额外的文件 - 什么都没有。好吧,这不是最好的方法,但它工作得很好,非常可靠(在非常旧的浏览器上测试时从未失败)并且加载速度非常快。

    几个月前发现它,并一直使用它,只需将此代码复制并粘贴到您的 CSS 中。

    background-image: url(data:image/png;base64,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);
    

    然后添加背景颜色

    background-color:#0094d0;
    

    演示:JSFiddle

    来源: https://coderwall.com/p/m-uwvg

    【讨论】:

    • 现在(2013 年)这比所有其他答案都更正确。
    • 代码的url() 部分到底发生了什么?有没有办法自定义粒度和其他参数?
    • @tobias47n9e URL 部分中的数据只是一个小图像。您可以将其更改为任何图像 URI 数据(谷歌“将图像转换为 URI)。注意它是您想要的 uri 数据或 urL!
    • @tim.baker 太棒了。谢谢!
    • @corysimmons 不正确。要将其与渐变一起使用,只需在同一 background-image 属性中附加一个逗号和渐变即可。
    【解决方案6】:

    为了新颖,这里是一些没有使用数据 URI 的纯 CSS 噪音:

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

    更多关于它是如何创建的信息:http://jollo.org/LNT/public/css-noise.html

    【讨论】:

    • 这是如何工作的?只是一堆渐变相互加减?
    【解决方案7】:

    使用 SVG 过滤器和 CSS 渐变创建纹理(噪声)

    您想要渐变中的噪点?你很幸运!

    Perlin noise 是一种梯度噪声。 SVG 标准指定了一个名为 <feTurbulence> 的过滤器原语,它实现了 Perlin 函数。它允许合成云或大理石等人造纹理——你想要的噪点。

    第 1 步:定义 SVG 图形

    创建一个名为 noise.svg 的小型 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>
    

    这个图形定义了两个矩形。第一个是用纯色填充的。第二个是半透明的,应用了噪声过滤器。第二个矩形覆盖在第一个矩形上以提供噪声效果。

    SVG 选项

    1. 拳头最明显的是可以改变图形的尺寸。但是,CSS background-repeat 属性可用于填充元素,因此 300×300 就足够了。

    2. 过滤器的type属性可以是fractalNoiseturbulence,指定过滤功能。两者都提供了不同的视觉效果,但在我看来,噪声过滤器更加微妙。

    3. 过滤器的baseFrequency 属性可以在0.5–0.9 的范围内分别提供精细纹理的路线。在我看来,这个范围对于任一过滤器来说都是视觉上的最佳选择。

    4. 可以更改第一个矩形的fill 以提供不同的基色。然而,后来,我们基本上将这种颜色与半透明的 CSS 渐变相结合,它也定义了一种颜色。所以白色是一个很好的起点。

    5. 第二个矩形的opacity 可以在 0.2–0.9 的范围内设置过滤器强度,数值越大,强度越大。

    此时,您可以调整上述选项,通过 CSS 将此噪声图形设置为背景图像,然后就可以结束了。但如果你想要渐变,比如 OP,请转到第 2 步。

    第 2 步:应用 CSS 渐变

    使用background-image 属性,您可以将SVG 噪声图形设置为任何元素的背景并覆盖gradient。在本例中,我将噪声图形应用到整个身体并覆盖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');
    }
    

    linear-gradient() 函数创建一个伪图像,该图像堆叠在 noise.svg 之上。结果是一个半透明的渐变,我们的噪声通过它显示出来。

    CSS 选项

    1. 首先,最明显的是,可以更改定义的渐变颜色。但是,如果您想要没有渐变的纯色,请使两个端点颜色相等。好处是您可以在整个站点或项目之间使用带有或不带有渐变的相同噪声图。

    2. 使用*-gradient() functions 创建的多个图像可以叠加在噪声图形上,并且可以在单个渐变函数中指定两个以上的颜色参数和角度,以提供各种酷炫的视觉效果。

    3. 渐变参数的不透明度——即rgba() 和 hsla() — 可以增加以增强定义的颜色并降低噪声级别。同样,0.2–0.9 是一个理想的范围。

    结论

    这是一个高度可定制且重量极轻(约 400 字节)的解决方案,可让您简单地定义任何颜色或渐变的噪点。虽然这里有几个旋钮可以转动,但这仅仅是开始。还有其他 SVG 滤镜原语,例如 &lt;feGaussianBlur&gt;&lt;feColorMatrix&gt;,它们可以提供额外的结果。

    【讨论】:

    • 有关我如何应用此技术来匹配给定渐变的示例,请参阅 my answerthis question
    • 你能链接到演示吗?
    • 您还可以使用 CSS 将 SVG 过滤器直接应用于元素,例如 body {filter: url(#n)}
    • @ClintPachl 这么好的解决方案!谢谢你。比使用画布更有效。对于任何想看动画版本的人,我在 stackblitz stackblitz.com/edit/react-ts-xc2kyo 中创建了一个示例
    【解决方案8】:

    我找到了一种方法,没有任何图像,radial-gradient 只有一个div

    首先我想展示一个径向渐变的例子。假设我们想在我们想要的坐标处创建一个圆。第一个圈是x=120y=80,第二个圈是x=20y=20。为了更好地理解我们将在下面编写的函数,我们可以考虑这个例子。

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

    我们将为数千行渐变编写一个@mixin 函数。

    一个 SCSS 函数:

    @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;
    }
    

    用法:

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

    Result

    如果我们想根据 % 值来制造噪音?

    我们可以使用这个函数。

    @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

    【讨论】:

      【解决方案9】:

      基于 Clint Pachl 的回答,我使用 CSS 的 mix-blend-mode 来获得更颗粒的效果,并有选择地对构成渐变的颜色进行打孔。

      示例代码见https://jsfiddle.net/jimmmy/2ytzh30w/

      更新:我在 CSS-Tricks 中写了一篇关于它的文章:Grainy Gradients

      【讨论】:

        猜你喜欢
        • 2011-06-12
        • 2011-10-16
        • 2012-02-17
        • 2012-08-31
        • 2011-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多