web-dev-qa-db-ja.com

SVG:外部CSSがテキストのインラインスタイルを上書きするのはなぜですか?

D3.jsチャートの長いテキスト文字列を視覚的に「切り捨てる」方法としてSVGgradientFillを使用して遊んでいます。

塗りつぶしの外部cssスタイルは、SVGのインライングラデーション塗りつぶしスタイルをオーバーライドするようです...常にそうですか?どうすればそのグラデーション塗りつぶしを強制できますか?

このテストケースでは、svg defsで線形グラデーションを定義してから、2つのテキストグループにグラデーション塗りつぶしを適用しました。 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;
}

最初のグループにはグラデーションの塗りつぶしがあり、2番目のグループにはありません。

インラインスタイルを優先するべきではありませんか?

ありがとう!

28
rolfsf

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>
32
Ben Lesh

SVG仕様から

CSSをサポートするユーザーエージェントの場合、プレゼンテーション属性は、CSS以外のプレゼンテーションヒントの優先順位([CSS2]、セクション6.4.4)で説明されているルールに従って、対応するCSSスタイルルールに変換する必要があります。著者スタイルシートコレクションの最初の新しい著者スタイルシートに概念的に挿入されます。したがって、プレゼンテーション属性は、作成者スタイルシートの先頭に配置された、特異度がゼロの対応するCSSスタイルルールに置き換えられたかのように、CSS2カスケードに参加します。一般に、これは、プレゼンテーション属性の優先度が、作成者のスタイルシートまたは「スタイル」属性で指定されている他のCSSスタイルルールよりも低いことを意味します。

したがって、プレゼンテーション属性ではなくインラインスタイルを使用できます。

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

私の場合、d3チェーンでattrstyleに置き換えるのと同じくらい簡単でした。

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