Background Color of Text in Svg

Background color of text in SVG

No this is not possible, SVG elements do not have background-... presentation attributes.

To simulate this effect you could draw a rectangle behind the text attribute with fill="green" or something similar (filters). Using JavaScript you could do the following:

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

SVG text background color with border radius and padding that matches the text width

if you can use script, you can use this little function. It handles some of the CSS values. You could however implement whatever you need...

function makeBG(elem) {  var svgns = "http://www.w3.org/2000/svg"  var bounds = elem.getBBox()  var bg = document.createElementNS(svgns, "rect")  var style = getComputedStyle(elem)  var padding_top = parseInt(style["padding-top"])  var padding_left = parseInt(style["padding-left"])  var padding_right = parseInt(style["padding-right"])  var padding_bottom = parseInt(style["padding-bottom"])  bg.setAttribute("x", bounds.x - parseInt(style["padding-left"]))  bg.setAttribute("y", bounds.y - parseInt(style["padding-top"]))  bg.setAttribute("width", bounds.width + padding_left + padding_right)  bg.setAttribute("height", bounds.height + padding_top + padding_bottom)  bg.setAttribute("fill", style["background-color"])  bg.setAttribute("rx", style["border-radius"])  bg.setAttribute("stroke-width", style["border-top-width"])  bg.setAttribute("stroke", style["border-top-color"])  if (elem.hasAttribute("transform")) {    bg.setAttribute("transform", elem.getAttribute("transform"))  }  elem.parentNode.insertBefore(bg, elem)}

var texts = document.querySelectorAll("text")for (var i = 0; i < texts.length; i++) { makeBG(texts[i])}
text {  background: red;  border-radius: 5px;  border: 2px solid blue;  padding: 5px}
text:nth-of-type(2) { background: orange; border-color: red}
g text { border-width: 4px}
<svg width="400px" height="300px">  <text x="20" y="40">test text</text>  <text x="20" y="80" transform="rotate(10,20,55)">test with transform</text>    <g transform="translate(0,100) rotate(-10,20,60) ">    <text x="20" y="60">test with nested transform</text>  </g></svg>

SVG - Text with background color and rounded borders

You can do this with a filter in two alternative ways:

  1. Do a flood, blur it, then clip the low opacities, then dial up the remaining opacity to full
  2. Smuggle in a rounded corner rect via feImage and use relative sizing to stretch it

In both cases padding is relative so if your text is too long, the rounded corners will overflow the filter area. Unlike CSS, you can't combine relative and absolute sizings in SVG (well SVG 1.1 at least). So this is as good as you get.

Since you're really looking for HTML text behavior but you want it in SVG, you might want to consider using a foreignObject and embedding HTML text that way.

<svg width="800px" height="600px"><defs>  <filter id="rounded-corners" x="-5%" width="110%" y="0%" height="100%"><feFlood flood-color="#FFAA55"/><feGaussianBlur stdDeviation="2"/><feComponentTransfer>  <feFuncA type="table"tableValues="0 0 0 1"/></feComponentTransfer>
<feComponentTransfer> <feFuncA type="table"tableValues="0 1 1 1 1 1 1 1"/></feComponentTransfer> <feComposite operator="over" in="SourceGraphic"/> </filter> <filter id="rounded-corners-2" primitiveUnits="objectBoundingBox"><feImage preserveAspectRatio="none" width="110%" height="110%" x="-5%" y="0%" xlink:href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' x='0px' y='0px' viewBox='0 0 400 40' height='40' width='400'%3E%3Crect fill='red' x='0' y='0' rx='10' ry='10' width='400' height='40'/%3E%3C/svg%3E"/> <feComposite operator="over" in="SourceGraphic"/> </filter> </defs>
<text filter="url(#rounded-corners)" x="20" y="40" style="font-size:30">Blur & opacity filter</text> <text filter="url(#rounded-corners)" x="20" y="80" style="font-size:30"> But the x padding is relative and overflows with long text</text> <text filter="url(#rounded-corners-2)" x="20" y="140" style="font-size:30">feImage and a rect filter</text> <text filter="url(#rounded-corners-2)" x="20" y="180" style="font-size:30">But you still can't get away from relative padding</text>
</svg>

Change background-color in svg-imge with text inside it

To achieve this, you need to add pointer-events: none; to your <text> tag.

CSS

.svg .number {
font-size: 19px;
pointer-events: none; /* <-- Add This */
}

JSFiddle

SVG text color with correspond to background

The approach to use clip paths has already been described by squeamish ossifrage's answer. I have put together a working snippet doing it the d3 way:

var svg = d3.select("body")    .append("svg")    .attr({        width: 400,        height: 400    });
var textOut = svg.append("text") .attr({ x: 120, y: 66 }) .style({ fill: "black", stroke: "none" }) .text("Description");
var rect = svg.append("rect") .attr({ id: "rect", x: 50, y: 50, width: 100, height: 20 }) .style({ fill: "limegreen", stroke: "darkgreen" });
svg.append("clipPath") .attr("id", "clip") .append("use") .attr("xlink:href", "#rect");
var textIn = svg.append("text") .attr({ x: 120, y: 66 }) .style({ fill: "white", stroke: "none", "clip-path": "url(#clip)" }) .text("Description");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

How to change the color of an svg element?

You can't change the color of an image that way. If you load SVG as an image, you can't change how it is displayed using CSS or Javascript in the browser.

If you want to change your SVG image, you have to load it using <object>, <iframe> or using <svg> inline.

If you want to use the techniques in the page, you need the Modernizr library, where you can check for SVG support and conditionally display or not a fallback image. You can then inline your SVG and apply the styles you need.

See :

#time-3-icon {   fill: green;}
.my-svg-alternate { display: none;}.no-svg .my-svg-alternate { display: block; width: 100px; height: 100px; background-image: url(image.png);}
<svg width="96px" height="96px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve"><path id="time-3-icon" d="M256,50C142.229,50,50,142.229,50,256c0,113.77,92.229,206,206,206c113.77,0,206-92.23,206-206 C462,142.229,369.77,50,256,50z M256,417c-88.977,0-161-72.008-161-161c0-88.979,72.008-161,161-161c88.977,0,161,72.007,161,161 C417,344.977,344.992,417,256,417z M382.816,265.785c1.711,0.297,2.961,1.781,2.961,3.518v0.093c0,1.72-1.223,3.188-2.914,3.505 c-37.093,6.938-124.97,21.35-134.613,21.35c-13.808,0-25-11.192-25-25c0-9.832,14.79-104.675,21.618-143.081 c0.274-1.542,1.615-2.669,3.181-2.669h0.008c1.709,0,3.164,1.243,3.431,2.932l18.933,119.904L382.816,265.785z"/></svg>
<image class="my-svg-alternate" width="96" height="96" src="ppngfallback.png" />


Related Topics



Leave a reply



Submit