SVG: 为什么外部 CSS 会覆盖文本的内联样式?

33

我正在尝试使用SVG渐变填充作为在d3.js图表中视觉上“截断”长文本字符串的方法。

似乎外部CSS样式的填充会覆盖SVG内联渐变填充样式...这种情况总是这样吗?我该如何强制使用渐变填充?

在这个测试案例中,我已经在SVG定义中定义了一个线性渐变,然后将渐变填充应用于两组文本。 http://jsfiddle.net/rolfsf/uX2kH/3/

var labelColWidth = 200;
var svg =  d3.select('#test').append('svg')
            .attr('width', 500)
            .attr('height', 500);

var defs = svg.append('svg:defs');

var textgradient = defs.append('svg:linearGradient')
            .attr('gradientUnits', 'userSpaceOnUse')
            .attr('x1', 0).attr('y1', 0).attr('x2', 40).attr('y2', 0)
            .attr('id', 'theGradient')
            .attr('gradientTransform',  'translate(' + (labelColWidth - 40) + ')');

    textgradient.append('svg:stop').attr('offset', '0%').attr('style', 'stop-color:rgb(0,0,0);stop-opacity:1')
    textgradient.append('svg:stop').attr('offset', '100%').attr('style', 'stop-color:rgb(0,0,0);stop-opacity:0');


var data = [[0, "xyzzy xyzzy"], [1, "xyzzy xyzzy xyzzy xyzzy xyzzy"], [2, "xyzzy xyzzy xyzzy xyzzy xyzzy xyzzy"], [3, "xyzzy xyzzy xyzzy"], [4, "xyzzy xyzzy"], [5, "xyzzy xyzzy xyzzy xyzzy xyzzy xyzzy xyzzy xyzzy xyzzy xyzzy"]];

var testGroup = svg.append('g')
    .attr('transform',  'translate(50, 100)');

var testGroup2 = svg.append('g')
    .attr('transform',  'translate(50, 250)')
    .attr('class', 'group2');

testGroup.selectAll('text').data(data)
  .enter().append('svg:text')
  .attr('fill', 'url(#theGradient)')
  .attr('x', 0)
  .attr('y', function(d, i) { return (i+1) * 20; })
  .text(function(d, i) { return d[1]; });

testGroup2.selectAll('text').data(data)
  .enter().append('svg:text')
  .attr('fill', 'url(#theGradient)')
  .attr('x', 0)
  .attr('y', function(d, i) { return (i+1) * 20; })
  .text(function(d, i) { return d[1]; });

然后在CSS中,我为 .group2 文本定义了一种填充方式

.group2 text {
    fill: #000;
}

第一组有渐变填充,第二组没有。

内联样式不应该具有优先权吗?

谢谢!

3个回答

41

因为在SVG中,就像之前的HTML一样,样式优先于属性样式。

fill="red" 下面不是“内联样式”,style="fill:green" 内联样式。

<svg width="400" height="400">
  <text x="50" y="50" fill="red" style="fill:green">This will be green</text>
</svg>

同样地,如果您在外部定义了样式,那么它将获胜。

<style>
  text { fill: lime; }
</style>

<svg width="300" height="300">
  <text x="50" y="40" fill="red">This will be lime</text>
</svg>


嗯...那么如何应用渐变填充以覆盖任何预定义的文本填充呢? - rolfsf
1
"这个将会是石灰色" 是红色的。 - user3624702
1
@user3624702,这是因为有人编辑了它并搞砸了“运行代码片段”,所以它没有包括<style>标签。 - Ben Lesh

9

来自SVG规范

对于支持CSS的用户代理,呈现属性必须按照《非CSS呈现提示的优先级》([CSS2],6.4.4节)中描述的规则转换为相应的CSS样式规则,同时还需要澄清的是,这些呈现属性在概念上插入到一个新的作者样式表中,该样式表是作者样式表集合中的第一个。因此,呈现属性将参与CSS2层叠,就好像它们被放置在作者样式表的开头,并具有零特异性的相应CSS样式规则一样。通常,这意味着呈现属性的优先级低于在作者样式表或“style”属性中指定的其他CSS样式规则。

因此,您可以使用内联样式而不是呈现属性,例如:

.attr('style', 'fill : url(#theGradient)')

0
在我的情况下,只需在d3链中将attr替换为style就可以了。
.style('stroke', 'url(#gradient--min)')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接