web-dev-qa-db-fra.com

SVG: pourquoi les css externes remplacent-ils le style en ligne pour le texte?

Je joue avec l'utilisation d'un SVG dégradé comme moyen de "tronquer" visuellement de longues chaînes de texte dans un graphique d3.js.

Il semble qu'un style css externe pour le remplissage remplacera le style de remplissage du dégradé en ligne dans le fichier SVG ... est-ce toujours le cas? Comment puis-je appliquer ce remplissage en dégradé?

Dans ce cas de test, j'ai défini un dégradé linéaire dans svg defs, puis appliqué le remplissage en dégradé à deux groupes de texte. 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]; });

puis en CSS, je définis un remplissage pour le texte .group2

.group2 text {
    fill: #000;
}

le premier groupe a le remplissage en dégradé, le second groupe non.

Le style en ligne ne devrait-il pas avoir la priorité?

Merci!

25
rolfsf

Parce que, dans SVG, comme HTML avant cela, les styles ont la priorité sur le style des attributs.

fill="red" ci-dessous estPASun "style en ligne", style="fill:green"ESTun style en ligne.

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

De même, si vous avez un style défini à l'extérieur, il gagnera.

<style>
  text { fill: Lime; }
</style>
<svg width="300" height="300">
  <text x="50" y="40" fill="red">This will be Lime</text>
</svg>

31
Ben Lesh

A partir de la spécification SVG

Pour les agents utilisateurs prenant en charge CSS, les attributs de présentation doivent être convertis en règles de style CSS correspondantes, conformément aux règles décrites dans Précédente les indications de présentation non CSS ([CSS2], section 6.4.4), en précisant que les attributs de présentation sont: conceptuellement inséré dans une nouvelle feuille de style d'auteur qui est la première de la collection de feuilles de style d'auteur. Les attributs de présentation participeront donc à la cascade CSS2 comme s'ils étaient remplacés par les règles de style CSS correspondantes placées au début de la feuille de style d'auteur avec une spécificité égale à zéro. En général, cela signifie que les attributs de présentation ont une priorité inférieure à celle des autres règles de style CSS spécifiées dans les feuilles de style de l’auteur ou les attributs «style».

Vous pouvez donc utiliser un style en ligne plutôt qu'un attribut de présentation, par exemple.

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

Dans mon cas, c'était aussi simple que de remplacer attr par style dans la chaîne d3:

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