How to either determine SVG text box width or force line breaks after 'x' characters?

When working with SVG text elements, you often need to control text wrapping since SVG doesn't automatically wrap text like HTML. This tutorial shows how to measure text width using getBBox() and implement word wrapping.

The Problem

SVG text elements don't wrap automatically. Long text will extend beyond boundaries, requiring manual line breaks based on width measurements.

Using getBBox() for Text Measurement

The getBBox() method returns the bounding box dimensions of SVG elements, including text width and height.

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.3.0/raphael.min.js"></script>
</head>
<body>
    <div id="canvas"></div>
    <script>
        var paper = Raphael("canvas", 500, 300);
        var textElement = paper.text(50, 50, "Sample text").attr({
            'text-anchor': 'start',
            'font-size': 14
        });
        
        // Get text dimensions
        var bbox = textElement.getBBox();
        console.log("Text width:", bbox.width);
        console.log("Text height:", bbox.height);
        
        // Draw a rectangle around the text to visualize bounds
        paper.rect(bbox.x, bbox.y, bbox.width, bbox.height).attr({
            'fill': 'none',
            'stroke': 'red'
        });
    </script>
</body>
</html>

Implementing Word Wrapping

Here's how to wrap text by adding words one at a time and checking width:

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.3.0/raphael.min.js"></script>
</head>
<body>
    <div id="wrap-canvas"></div>
    <script>
        var paper = Raphael("wrap-canvas", 400, 200);
        var textElement = paper.text(20, 20).attr({
            'text-anchor': 'start',
            'font-size': 14
        });
        
        var maxWidth = 300;
        var content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis nec semper mauris. Sed gravida augue feugiat nulla ultrices efficitur.";
        var words = content.split(" ");
        var tempText = "";
        
        for (var i = 0; i < words.length; i++) {
            // Test adding the next word
            var testText = tempText + (tempText ? " " : "") + words[i];
            textElement.attr("text", testText);
            
            if (textElement.getBBox().width > maxWidth && tempText) {
                // Too wide, add line break
                tempText += "<br>" + words[i];
            } else {
                // Fits on current line
                tempText = testText;
            }
        }
        
        textElement.attr("text", tempText);
        
        // Draw boundary box to show max width
        paper.rect(20, 20, maxWidth, textElement.getBBox().height).attr({
            'fill': 'none',
            'stroke': 'blue',
            'stroke-dasharray': '5,5'
        });
    </script>
</body>
</html>

Alternative: Character-Based Line Breaks

For simpler cases, you can force line breaks after a specific number of characters:

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.3.0/raphael.min.js"></script>
</head>
<body>
    <div id="char-canvas"></div>
    <script>
        function wrapTextByCharacters(text, maxChars) {
            var result = "";
            for (var i = 0; i < text.length; i += maxChars) {
                result += text.substring(i, i + maxChars);
                if (i + maxChars < text.length) {
                    result += "<br>";
                }
            }
            return result;
        }
        
        var paper = Raphael("char-canvas", 400, 150);
        var longText = "This is a very long text that needs to be wrapped at specific character intervals.";
        var wrappedText = wrapTextByCharacters(longText, 25);
        
        paper.text(20, 50, wrappedText).attr({
            'text-anchor': 'start',
            'font-size': 14
        });
    </script>
</body>
</html>

Comparison of Methods

Method Accuracy Performance Use Case
getBBox() word wrapping High Slower Precise width control
Character-based breaking Medium Fast Simple fixed-width layouts

Key Points

  • getBBox() returns accurate dimensions after text is rendered
  • Test text width before committing to avoid overflow
  • Handle edge cases like single words longer than max width
  • Character-based wrapping works for monospace fonts

Conclusion

Use getBBox() for precise SVG text wrapping based on actual rendered width. For simpler cases, character-based line breaks offer a faster alternative with acceptable results.

Updated on: 2026-03-15T23:18:59+05:30

313 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements