Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

svg

I need to wrap a background around a text element inside an SVG, it needs to have padding and a border radius. The issue is the text will be dynamic so I need the background to expand the width of the text. I found a solution to this using foreign object but this isn't support in IE 11 which is a problem. Can anyone suggest a workaround.

like image 969
user3486427 Avatar asked Dec 04 '25 18:12

user3486427


1 Answers

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>
like image 135
Holger Will Avatar answered Dec 06 '25 13:12

Holger Will



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!