How can I create a box (rect
?) that resizes itself to fit the the text inside of it using SVG?
Asked
Active
Viewed 1.1k times
16
-
See also: http://stackoverflow.com/questions/2938779/svg-scaling-text-to-fit-container – Has QUIT--Anony-Mousse Aug 04 '12 at 17:32
-
The viewport attribute that's mentioned in that question has nothing to do with the answer here. – SSH This Dec 31 '12 at 20:08
-
Nice example with bbox https://bl.ocks.org/mbostock/1160929 – marioosh Nov 16 '17 at 08:43
2 Answers
8
Sorry the answer took me so long, but I was learning how to use ECMAScript with an XML DOM.
Alright. So suppose you have your document structure like so:
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="800"
height="600"
id="example_text">
<g id="layer1">
<text
x="123.4"
y="567.8"
id="text_holder">
<tspan id="tspan1">Text</tspan>
<tspan id="tspan2">More text</tspan>
</text>
</g>
<script type="text/ecmascript">
function create_from_rect (client_rect, offset_px) {
if (! offset_px) {offset_px=0;}
var box = document.createElementNS(
document.rootElement.namespaceURI,
'rect'
);
if (client_rect) {
box.setAttribute('x', client_rect.left - offset_px);
box.setAttribute('y', client_rect.top - offset_px);
box.setAttribute('width', client_rect.width + offset_px * 2);
box.setAttribute('height', client_rect.height + offset_px * 2);
}
return box;
}
function add_bounding_box (text_id, padding) {
var text_elem = document.getElementById(text_id);
if (text_elem) {
var f = text_elem.getClientRects();
if (f) {
var bbox = create_from_rect(f[0], padding);
bbox.setAttribute(
'style',
'fill: none;'+
'stroke: black;'+
'stroke-width: 0.5px;'
);
text_elem.parentNode.appendChild(bbox);
}
}
}
add_bounding_box('text_holder', 5);
</script>
</svg>
Adding the <script>
tag at the bottom of the root <svg>
element causes it to execute after it's created the DOM structure above it, just like JavaScript on a web page.

amphetamachine
- 27,620
- 12
- 60
- 72
-
Thanks, I'm extremely impressed with your answer. Its much more work to accomplish this than I expected. – Asa Ayers Jun 21 '10 at 22:25
-
I should add that I tried this when displaying in Firefox and it works, but am having trouble getting it to work in Chrome. – amphetamachine Jun 24 '10 at 06:22
2
Would the following approach make things any simpler?
var text_elem = document.getElementById(text_id);
var bbox = text_elem.getBBox();
and then use bbox's width and height to draw a rect?

JamieJag
- 1,541
- 2
- 11
- 18
-
Can you explain how that would make it simpler? How would I use the code your provided? – Asa Ayers Apr 19 '12 at 20:34
-
Unless I've not understood you correctly, all you're looking to do is draw a rectangle around the text, so the rect need only be drawn starting at the text element's x,y and with the bbox's width and height. I haven't tested the code, but I'd hazard the guess that checking for bbox not being null would not be necessary. I was being overly optimistic when I said my approach would simplify things; it would, but not dramatically – JamieJag Apr 20 '12 at 22:31