A quick note about SVG foreignObject

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 <foreignObject>.

Stuff & Nonsense about page SVG panel

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:

<symbol id="principles-bubble">

<use xlink:href="#principles-bubble"></use>

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 <foreignObject> element.

The <foreignObject> element allows elements from other XML namespaces like HTML to be included within SVG:

<text>WE BELIEVE…</text>
<p>in only working on projects where our experience adds value.</p>

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 foreignObject using width and 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>

With 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?


Working with clients for over 25 years

Contact us OK, LET’S TALK

Press to call 01745 851848