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

时间:2014-06-18 19:47:17

标签: css svg d3.js gradient

我正在使用SVG gradientFill作为在d3.js图表​​中直观“截断”长文本字符串的方法。

似乎填充的外部css样式将覆盖SVG中的内联渐变填充样式...总是如此?如何强制执行渐变填充?

在这个测试用例中,我在svg defs中定义了一个线性渐变,然后将渐变填充应用于两组文本。 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 个答案:

答案 0 :(得分:32)

因为在SVG中,就像之前的HTML一样,样式特朗普属性样式。

下面的

fill="red" NOT 是“内联样式”,style="fill:green" IS 是内联样式。

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

答案 1 :(得分:7)

来自SVG specification

  

对于支持CSS的用户代理,必须根据非CSS表示提示的优先顺序([CSS2],第6.4.4节)中描述的规则将表示属性转换为相应的CSS样式规则,并进一步说明表示属性在概念上插入到新的作者样式表中,这是作者样式表集合中的第一个。因此,表示属性将参与CSS2级联,就好像它们被放置在作者样式表开头的相应CSS样式规则所取代,特征为零。通常,这意味着表示属性的优先级低于作者样式表或“样式”属性中指定的其他CSS样式规则

因此,您可以使用内联样式而不是表示属性,例如

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

答案 2 :(得分:0)

就我而言,它就像在d3链中用attr替换style一样简单:

.style('stroke', 'url(#gradient--min)')