【问题标题】:SVG gradient using CSS使用 CSS 的 SVG 渐变
【发布时间】:2012-12-12 15:31:38
【问题描述】:

我正在尝试将渐变应用于 SVG rect 元素。

目前,我正在使用fill 属性。在我的 CSS 文件中:

rect {
    cursor: pointer;
    shape-rendering: crispEdges;
    fill: #a71a2e;
}

在浏览器中查看时,rect 元素具有正确的填充颜色。

但是,我想知道是否可以对这个元素应用线性渐变?

【问题讨论】:

    标签: css svg gradient linear-gradients


    【解决方案1】:

    只需在 CSS 中使用您将在 fill 属性中使用的任何内容。 当然,这需要您在 SVG 中的某处定义线性渐变。

    这是一个完整的例子:

    rect {
        cursor: pointer;
        shape-rendering: crispEdges;
        fill: url(#MyGradient);
    }
    <svg width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
          <style type="text/css">
            rect{fill:url(#MyGradient)}
          </style>
          <defs>
            <linearGradient id="MyGradient">
              <stop offset="5%" stop-color="#F60" />
              <stop offset="95%" stop-color="#FF6" />
            </linearGradient>
          </defs>
          
          <rect width="100" height="50"/>
        </svg>

    【讨论】:

    • 所以我在一个单独的文件中创建了该渐变,并以这种方式使用fillfill: url(../js/gradient.svg#MyGradient);。这是正确的方法吗?
    • @HrishikeshChoudhari:是的,这是正确的,但 Chrome 和我认为 Safari 也不支持从其他文件中引用元素。不确定 IE9(目前无法测试,请尝试一下)。
    • 致任何阅读本文并询问“fill: linear-gradient (...) 怎么样?”的人fill 需要一个围绕 CSS2 &lt;color&gt; 类构建的 &lt;paint&gt;。换句话说,在我写这篇评论时,这个答案是目前通过 CSS 完成的唯一方法。您需要添加一个linearGradient 元素。最后,通过SVG2 的 w3 工作草案,似乎对填充 css 规则的linear-gradient 的支持尚未也可能不会进入规范。
    • 这种情况下如何改变方向?
    • @AwQiruiGuo 看看MDN(特别是gradientTransform属性)
    【解决方案2】:

    2019 年答案

    借助全新的 CSS 属性,您可以更灵活地使用变量,也就是 custom properties

    .shape {
      width:500px;
      height:200px;
    }
    
    .shape .gradient-bg {
      fill: url(#header-shape-gradient) #fff;
    }
    
    #header-shape-gradient {
      --color-stop: #f12c06;
      --color-bot: #faed34;
    }
    <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" class="shape">
      <defs>
        <linearGradient id="header-shape-gradient" x2="0.35" y2="1">
            <stop offset="0%" stop-color="var(--color-stop)" />
            <stop offset="30%" stop-color="var(--color-stop)" />
            <stop offset="100%" stop-color="var(--color-bot)" />
          </linearGradient>
      </defs>
      <g>
        <polygon class="gradient-bg" points="0,0 100,0 0,66" />
      </g>
    </svg>

    只需在渐变中为每个stop 设置一个命名变量,然后在 css 中根据需要进行自定义。您甚至可以使用 javascript 动态更改它们的值,例如:

    document.querySelector('#header-shape-gradient').style.setProperty('--color-stop', "#f5f7f9");
    

    【讨论】:

    • 在 IE 中不支持。
    • @MaciejKwas,你错了。旧的浏览器不会永远存在,所以现在还没有准备好的公司将在那时准备好。如果有人还没有准备好放弃他的一部分受众,这并不意味着他还没有准备好进行更改,这意味着他更愿意在以后利用这些更改来留住更多的受众。
    • @aoakeson IE 已死。寿终正寝。 Edge 也快死了,这是 2019 年的答案,所以 IE 不应该算在内。 IE 可以通过使用纯色来优雅地降级。
    • @aoakeson 我对在 2019 年遇到这种回应感到非常惊讶。作为开发人员,如果您认为 IE 中的 SVG 支持在这个级别上会永远,那就太天真了> 得到支持,更不用说 SO 的萌芽开发者,如果你打算支持 IE,就会给你一个臃肿、多变的答案来解决不必要的问题。
    【解决方案3】:

    在 Finesse 所写内容的基础上,这里有一种更简单的方法来定位 svg 并更改它的渐变。

    这是你需要做的:

    1. 为渐变元素中定义的每个色标分配类。
    2. 定位 css 并使用普通类更改每个停靠点的停靠点颜色。
    3. 赢了!

    使用类而不是 :nth-child 的一些好处是,如果您重新排列停靠点,它不会受到影响。此外,它还明确了每个班级的意图 - 您会想知道是否需要在第一个孩子或第二个孩子身上涂上蓝色。

    我已经在所有 Chrome、Firefox 和 IE11 上测试过:

    .main-stop {
      stop-color: red;
    }
    .alt-stop {
      stop-color: green;
    }
    <svg class="green" width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
      <linearGradient id="gradient">
        <stop class="main-stop" offset="0%" />
        <stop class="alt-stop" offset="100%" />
      </linearGradient>
      <rect width="100" height="50" fill="url(#gradient)" />
    </svg>

    在此处查看可编辑的示例: https://jsbin.com/gabuvisuhe/edit?html,css,output

    【讨论】:

    • 不足之处在于您不确定停止类名称是什么以及它们的顺序。实际上,解决方案都一样好,唯一的区别是 CSS 选择器。
    【解决方案4】:

    这是一个解决方案,您可以只使用 CSS 添加渐变并更改其颜色:

    // JS is not required for the solution. It's used only for the interactive demo.
    const svg = document.querySelector('svg');
    document.querySelector('#greenButton').addEventListener('click', () => svg.setAttribute('class', 'green'));
    document.querySelector('#redButton').addEventListener('click', () => svg.setAttribute('class', 'red'));
    svg.green stop:nth-child(1) {
      stop-color: #60c50b;
    }
    svg.green stop:nth-child(2) {
      stop-color: #139a26;
    }
    
    svg.red stop:nth-child(1) {
      stop-color: #c84f31;
    }
    svg.red stop:nth-child(2) {
      stop-color: #dA3448;
    }
    <svg class="green" width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
      <linearGradient id="gradient">
        <stop offset="0%" />
        <stop offset="100%" />
      </linearGradient>
      <rect width="100" height="50" fill="url(#gradient)" />
    </svg>
    
    <br/>
    <button id="greenButton">Green</button>
    <button id="redButton">Red</button>

    【讨论】:

      【解决方案5】:

      谢谢大家, 为您所有的准确答复。

      在 shadow dom 中使用 svg,我在 svg 中添加我需要的 3 个线性渐变,在 . 我将 css 填充规则放在 web 组件上,继承 od 填充完成了这项工作。

          <svg viewbox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
            <path
              d="m258 0c-45 0-83 38-83 83 0 45 37 83 83 83 45 0 83-39 83-84 0-45-38-82-83-82zm-85 204c-13 0-24 10-24 23v48c0 13 11 23 24 23h23v119h-23c-13 0-24 11-24 24l-0 47c0 13 11 24 24 24h168c13 0 24-11 24-24l0-47c0-13-11-24-24-24h-21v-190c0-13-11-23-24-23h-123z"></path>
          </svg>
          
          <svg height="0" width="0">
            <defs>
              <linearGradient id="lgrad-p" gradientTransform="rotate(75)"><stop offset="45%" stop-color="#4169e1"></stop><stop offset="99%" stop-color="#c44764"></stop></linearGradient>
              <linearGradient id="lgrad-s" gradientTransform="rotate(75)"><stop offset="45%" stop-color="#ef3c3a"></stop><stop offset="99%" stop-color="#6d5eb7"></stop></linearGradient>
              <linearGradient id="lgrad-g" gradientTransform="rotate(75)"><stop offset="45%" stop-color="#585f74"></stop><stop offset="99%" stop-color="#b6bbc8"></stop></linearGradient>
            </defs>
          </svg>
          
          <div></div>
      
          <style>
            :first-child {
              height:150px;
              width:150px;
              fill:url(#lgrad-p) blue;
            }
            div{
              position:relative;
              width:150px;
              height:150px;
              fill:url(#lgrad-s) red;
            }
          </style>
          <script>
            const shadow = document.querySelector('div').attachShadow({mode: 'open'});
            shadow.innerHTML="<svg viewbox=\"0 0 512 512\">\
              <path d=\"m258 0c-45 0-83 38-83 83 0 45 37 83 83 83 45 0 83-39 83-84 0-45-38-82-83-82zm-85 204c-13 0-24 10-24 23v48c0 13 11 23 24 23h23v119h-23c-13 0-24 11-24 24l-0 47c0 13 11 24 24 24h168c13 0 24-11 24-24l0-47c0-13-11-24-24-24h-21v-190c0-13-11-23-24-23h-123z\"></path>\
            </svg>\
            <svg height=\"0\">\
            <defs>\
              <linearGradient id=\"lgrad-s\" gradientTransform=\"rotate(75)\"><stop offset=\"45%\" stop-color=\"#ef3c3a\"></stop><stop offset=\"99%\" stop-color=\"#6d5eb7\"></stop></linearGradient>\
              <linearGradient id=\"lgrad-g\" gradientTransform=\"rotate(75)\"><stop offset=\"45%\" stop-color=\"#585f74\"></stop><stop offset=\"99%\" stop-color=\"#b6bbc8\"></stop></linearGradient>\
            </defs>\
          </svg>\
          ";
          </script>

      第一个是普通的SVG, 第二个在 shadow dom 内。

      【讨论】:

        【解决方案6】:

        以下是如何在目标元素上设置 linearGradient

        <style type="text/css">
            path{fill:url('#MyGradient')}
        </style>
        <defs>
            <linearGradient id="MyGradient">
                <stop offset="0%" stop-color="#e4e4e3" ></stop>
                <stop offset="80%" stop-color="#fff" ></stop>
            </linearGradient>
        </defs>
        

        【讨论】:

        • 问题中没有任何内容暗示使用 php。
        猜你喜欢
        • 2022-01-10
        • 1970-01-01
        • 2015-06-23
        • 1970-01-01
        • 1970-01-01
        • 2014-02-18
        • 2011-10-20
        • 2021-11-26
        相关资源
        最近更新 更多