When I was developing the SVG panel for principles on the Stuff & Nonsense about page, I ran into a problem which could only be fixed using
This panel includes eight of the things “we believe…,” in speech bubbles. Each bubble is a separate SVG element nested inside a container SVG. To avoid repeating identical code eight times to create the bubbles, I define the bubble shape as a
symbol once and then I reference it multiple times:
<svg> <symbol id="principles-bubble"> <path>…</path> </symbol> <svg> <use xlink:href="#principles-bubble"></use> … </svg> </svg>
A bubble includes an SVG
<text> element for “WE BELIEVE…,”, but the trouble came when I needed to include wrapping text. Text in SVG doesn’t wrap like HTML text. Using
<tspan> elements makes sense for separating lines in headlines, but is too restrictive for text in these bubbles. I don’t want to specify where line-breaks occur, I want text to flow and wrap naturally. A little research led to the
The <foreignObject> element allows elements from other XML namespaces like HTML to be included within SVG:
<svg> <text>WE BELIEVE…</text> <foreignObject> <p>in only working on projects where our experience adds value.</p> </foreignObject> </svg>
I include a paragraph, but a
foreignObject can just as easily include any other HTML element and even groups of elements. Like other elements in SVG, I can size a
height attributes, and position it using
x y coordinates. I can apply a fill or stroke, add a filter or mask, and even clip its shape.
<svg xmlns:xhtml="http://www.w3.org/1999/xhtml"> <use xlink:href="#principles-bubble"></use> <text x="20" y="50">WE BELIEVE…</text> <foreignObject x="20" y="65" width="210" height="100"> <p>in long-term creative partnerships…</p> </foreignObject> </svg>
foreignObject, my principles text wraps inside each bubble. Exactly like I want it too.
If you like this post, why not buy an Art Direction for the Web e-book for £12.99?