使用 CSS 的 SVG 渐变

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14051351/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 21:07:19  来源:igfitidea点击:

SVG gradient using CSS

csssvggradientlinear-gradients

提问by Hrishikesh Choudhari

I'm trying to get a gradient applied to an SVG rectelement.

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

Currently, I'm using the fillattribute. In my CSS file:

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

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

And the rectelement has the correct fill color when viewed in the browser.

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

However, I'd like to know if I can apply a linear gradient to this element?

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

回答by Thomas W

Just use in the CSS whatever you would use in a fillattribute. Of course, this requires that you have defined the linear gradient somewhere in your SVG.

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

Here is a complete example:

这是一个完整的例子:

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>

回答by Maciej Kwas

2019 Answer

2019 答案

With brand new css properties you can have even more flexibility with variables aka custom properties

使用全新的 css 属性,您可以更灵活地使用变量 aka 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>

Just set a named variable for each stopin gradient and then customize as you like in css. You can even change their values dynamically with javascript, like:

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

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

回答by kumarharsh

Building on top of what Finesse wrote, here is a simpler way to target the svg and change it's gradient.

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

This is what you need to do:

这是你需要做的:

  1. Assign classes to each color stop defined in the gradient element.
  2. Target the css and change the stop-color for each of those stops using plain classes.
  3. Win!
  1. 为渐变元素中定义的每个色标分配类。
  2. 定位 css 并使用普通类更改每个停靠点的停止颜色。
  3. 赢!

Some benefits of using classes instead of :nth-childis that it'll not be affected if you reorder your stops. Also, it makes the intent of each class clear - you'll be left wondering whether you needed a blue color on the first child or the second one.

使用类而不是类的一些好处:nth-child是,如果您重新排序止损,它不会受到影响。此外,它使每个班级的意图变得清晰 - 您会想知道您是否需要第一个孩子或第二个孩子的蓝色。

I've tested it on all Chrome, Firefox and IE11:

我已经在所有 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>

See an editable example here: https://jsbin.com/gabuvisuhe/edit?html,css,output

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

回答by Finesse

Here is a solution where you can add a gradient and change its colours using only CSS:

这是一个解决方案,您可以仅使用 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>

回答by Roland Gautier

Thank you everyone, for all your precise replys.

谢谢大家,谢谢大家的准确回复。

Using the svg in a shadow dom, I add the 3 linear gradients I need within the svg, inside a . I place the css fill rule on the web component and the inheritance od fill does the job.

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

see my test in codepen

在 codepen 中查看我的测试

The first one is normal SVG, the second one is inside a shadow dom.

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

回答by axelparatre

Here is how to set a linearGradienton a target element:

以下是在目标元素上设置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>