使用CSS的SVG渐变


102

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

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

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

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

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

Answers:


94

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


2
因此,我在一个单独的文件中创建了该渐变,并使用了fill这种方式:fill: url(../js/gradient.svg#MyGradient);。这是正确的方法吗?
赫里希克什(Hrishikesh Choudhari)2012年

@HrishikeshChoudhari:是的,这是正确的,但是Chrome和我认为Safari也不支持引用其他文件中的元素。不确定IE9(目前无法测试,请尝试一下)。
Thomas W

53
对于任何读过此书并问“怎么fill: linear-gradient (...)回事”的人 fill需要一个<paint>围绕CSS2 <color>类构建的。换句话说,在我编写此注释时,此答案是当前通过CSS的唯一方法。您需要添加一个linearGradient元素。最后,通过SVG2的w3工作草案,似乎linear-gradient对fill css规则的支持还没有并且可能没有纳入规范。
亚瑟·韦伯org'3

在这种情况下如何改变方向?
AGamePlayer

1
@AwQiruiGuo看看MDN(特别是gradientTransform属性)
Thomas W

34

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

3
在IE中不支持。
aoakeson

3
CSS自定义属性已经存在很长时间了,如果有人不准备使用它们,那么他将永远不会为更改做准备。
Maciej Kwas '19

1
@MaciejKwas,你错了。旧的浏览器不会永远存在,因此那些还没有准备好的公司将会准备就绪。而且,如果有人不准备抛弃一部分观众,这并不意味着他还没有做好改变的准备,这意味着他更喜欢稍后利用这些改变来保持更大的受众。
Finesse

19
@aoakeson IE已死。生命终结。Edge也快要死了,这是2019年的答案,所以IE不应该算在内。通过使用纯色,IE可以正常降级。
西普里安

5
@aoakeson我惊人意外地遇到那种在2019年响应的你会天真开发商承担SVG支持IE浏览器在这个层面上会永远的支持,更谈不上对SO给你一个臃肿崭露头角的开发者,如果您打算支持IE,则可以填写不必要的答案。
詹姆斯·马丁·戴维斯

18

在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选择器。
Finesse

3
我认为这是对OP问题的最佳现代答案。
基本元素

9

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


2

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

在阴影dom中使用svg,我在svg中的内添加了3个线性渐变。我将css fill规则放在Web组件上,继承od fill可以完成这项工作。

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

在Codepen中查看我的测试

第一个是正常的SVG,第二个是在影子dom内部。


-4

这是在目标元素上设置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。
ACJ
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.