web-dev-qa-db-fra.com

Couleur d'arrière-plan du texte en SVG

Je veux colorer le fond de svg text semblable à background-color en css

Je n'ai pu trouver que de la documentation sur fill, qui colore le texte lui-même

Est-ce même possible?

73
Nick Ginanto

Non, ce n'est pas possible, les éléments SVG n'ont pas d'attributs de présentation background-...

Pour simuler cet effet, vous pouvez dessiner un rectangle derrière l'attribut text avec fill="green" ou quelque chose de similaire (filtres). En utilisant JavaScript, vous pouvez effectuer les opérations suivantes: 

var ctx = document.getElementById("the-svg"),
textElm = ctx.getElementById("the-text"),
SVGRect = textElm.getBBox();

var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
    rect.setAttribute("x", SVGRect.x);
    rect.setAttribute("y", SVGRect.y);
    rect.setAttribute("width", SVGRect.width);
    rect.setAttribute("height", SVGRect.height);
    rect.setAttribute("fill", "yellow");
    ctx.insertBefore(rect, textElm);
72
Roger

Vous pouvez utiliser un filtre pour générer l’arrière-plan.

<svg width="100%" height="100%">
  <defs>
    <filter x="0" y="0" width="1" height="1" id="solid">
      <feFlood flood-color="yellow"/>
      <feComposite in="SourceGraphic" operator="xor" />
    </filter>
  </defs>
<text filter="url(#solid)" x="20" y="50" font-size="50">solid background</text>
</svg>

61
Robert Longson

Non, vous ne pouvez pas ajouter de couleur de fond aux éléments SVG. Vous pouvez le faire par programme avec d3 .

var text = d3.select("text");
var bbox = text.node().getBBox();
var padding = 2;
var rect = self.svg.insert("rect", "text")
    .attr("x", bbox.x - padding)
    .attr("y", bbox.y - padding)
    .attr("width", bbox.width + (padding*2))
    .attr("height", bbox.height + (padding*2))
    .style("fill", "red");
14
nnattawat

La solution que j'ai utilisée est:

<svg>
  <line x1="100" y1="100" x2="500", y2="100" style="stroke:black; stroke-width: 2"/>    
  <text x="150" y="105" style="stroke:white; stroke-width:0.6em">Hello World!</text>
  <text x="150" y="105" style="fill:black">Hello World!</text>  
</svg>

Un élément de texte en double est en cours de placement, avec les attributs de trait et de largeur de trait. Le trait doit correspondre à la couleur d'arrière-plan et la largeur du trait doit être juste assez grande pour créer un "splodge" sur lequel écrire le texte.

Un peu de bidouille et il y a des problèmes potentiels, mais cela fonctionne pour moi!

9
dbarton_uk

Réponse de Robert Longson (@RobertLongson) avec modifications: 

<svg width="100%" height="100%">
  <defs>
    <filter x="0" y="0" width="1" height="1" id="solid">
      <feFlood flood-color="yellow"/>
      <feComposite in="SourceGraphic" operator="xor"/>
    </filter>
  </defs>
  <text filter="url(#solid)" x="20" y="50" font-size="50"> solid background </text>
  <text x="20" y="50" font-size="50">solid background</text>
</svg>

et nous n'avons ni bluring ni lourd "getBBox" :) Le rembourrage est fourni par des espaces blancs dans l'élément de texte avec filtre . Cela a fonctionné pour moi

3
Roman Belov

Au lieu d'utiliser une balise <text>, la balise <foreignObject> peut être utilisée, ce qui permet de créer du contenu XHTML avec CSS.

1
Chris G

c'est mon hack préféré (pas sûr que ça marche). Il fait référence à un élément qui n'est pas encore affiché, et cela fonctionne plutôt bien

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 620 40" preserveAspectRatio="xMidYMid meet">
    <defs>
        <filter x="-0.02" y="0" width="1.04" height="1.1" id="removebackground">
            <feFlood flood-color="#00ffff"/>
        </filter>
    </defs>

    <!--Draw the text--> 
    <use xlink:href="#mygroup" filter="url(#removebackground)" />
    <g id="mygroup">
        <text id="text1" x="9" y="20" style="text-anchor:start;font-size:14px;">custom text with background</text>  
        <line x1="200" y1="18" x2="200" y2="36" stroke="#000" stroke-width="5"/> 
        <line x1="120" y1="27" x2="203" y2="27" stroke="#000" stroke-width="5"/> 
    </g>
</svg>

1
Calimero100582

Vous pouvez combiner le filtre avec le texte.

<!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8 />
    <title>SVG colored patterns via mask</title>
  </head>
  <body>
    <svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <filter x="0" y="0" width="1" height="1" id="bg-text">
          <feFlood flood-color="white"/>
          <feComposite in="SourceGraphic" operator="xor" />
        </filter>
      </defs>
          <!-- something has already existed -->
    <rect fill="red" x="150" y="20" width="100" height="50" />
    <circle cx="50"  cy="50" r="50" fill="blue"/>
      
      <!-- Text render here -->
      <text filter="url(#bg-text)" fill="black" x="20" y="50" font-size="30">text with color</text>
      <text fill="black" x="20" y="50" font-size="30">text with color</text>
    </svg>
  </body>
</html> 
0
Vu Phan

Vous pouvez ajouter du style à votre texte: 

  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); 
    text-shadow: rgb(255, 255, 255) -2px -2px 0px, rgb(255, 255, 255) -2px 2px 0px, 
     rgb(255, 255, 255) 2px -2px 0px, rgb(255, 255, 255) 2px 2px 0px;"

Blanc, dans cet exemple . Ne fonctionne pas dans IE :)

0
Jan Pi