block by nitaku 62f9489f6ab52e703400

Labels with line wrap (HTML in SVG)

Full Screen

This example shows a way to obtain line-wrapping labels using HTML code within SVG code, thanks to the foreignObject tag. Fundamental sections of the code come from this StackOverflow discussion.

Some comments: It is unclear (to me at least) how the whole XML namespace mess should be translated into HTML5, but the example as it is now is working at least on Chrome 36. A strange behavior I noticed is that the body element is omitted by the DOM, causing some discrepancies between HTML and CSS selectors.

index.html

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8">
        <meta name="description" content="Labels with line wrap (HTML in SVG)" />
        <title>Labels with line wrap (HTML in SVG)</title>
		<link type="text/css" href="index.css" rel="stylesheet"/>
	</head>
	<body>
        <svg height="500" width="960">
          <circle r="50" cx="200" cy="150" fill="teal"/>
          
          <foreignObject class="label" x="230" y="170" width="200" height="300">
            <body xmlns="//www.w3.org/1999/xhtml">
              <div>This is not a circle.<br>This is a <b>label</b> for the circle.</div>
            </body>
          </foreignObject>
          
          <circle r="100" cx="650" cy="310" fill="orange"/>
          
          <foreignObject class="label" x="700" y="350" width="200" height="300">
            <body xmlns="//www.w3.org/1999/xhtml">
              <div>This is a <i>longer</i> label.<br>I really don't know how to fill these lines with meaningful text, so I'll keep writing nonsense.</div>
            </body>
          </foreignObject>
        </svg>
        <script src="index.js"></script>
	</body>
</html>

index.css

svg {
  background: white;
}
.label > div, .label > body > div {
  padding: 8px;
  border: 1px solid #CCC;
  background: rgba(255,255,255,0.8);
  border-radius: 12px;
  border-top-left-radius: 0;
}