Native SVG text, drawn with <text>, never wraps on its own: a sentence too long for its intended width simply overflows the box, and no font tweak fixes that. On an infographic mixing shapes with explanatory paragraphs, that limit gets in the way fast.
<foreignObject> works around it by opening a window, right inside the SVG's own coordinates, where perfectly ordinary HTML content can be dropped in, with everything HTML already knows how to do, automatic line wrapping included.
Definition
<foreignObject> marks out a rectangle, positioned and sized in SVG coordinates, inside which content belonging to another markup language can be placed, most often HTML. That content is then laid out by the usual rules of HTML and CSS, not by SVG's rules: a paragraph behaves there like an ordinary paragraph, with automatic line breaks, margins, and an inherited font.
Main attributes
Four attributes are enough to frame the area: x and y place the top-left corner of the rectangle, width and height set its width and height. Unlike many other SVG elements, these dimensions are mandatory: without a width and a height set, <foreignObject> reserves no space at all, and its content shows up nowhere.
| Attribute | Role |
|---|---|
x, y | Position of the top-left corner |
width, height | Dimensions of the area, mandatory |
A concrete example
An infographic card combines a background drawn with <rect> and an explanatory paragraph whose exact length is not known ahead of time.
<svg viewBox="0 0 300 150" xmlns="http://www.w3.org/2000/svg">
<rect width="300" height="150" fill="#eef2ff" rx="12" />
<foreignObject x="20" y="20" width="260" height="110">
<div
xmlns="http://www.w3.org/1999/xhtml"
style="font-family: sans-serif;
font-size: 14px;
color: #1e293b;
line-height: 1.4;"
>
This paragraph is long enough to show that the text wraps automatically,
exactly like on an ordinary HTML page.
</div>
</foreignObject>
</svg>The same paragraph written with <text> and <tspan> would have needed the position of every line break worked out by hand, redone each time the text changes.
Difference with <text>
<text> is still the right call for a short label, a large number, or a single-line caption: light, crisp, with no dependency on an external layout engine. The problem shows up once the text length is not known ahead of time, a comment pulled from a database, or a caption translated into a language wordier than the original. With <text>, every word's width would need measuring in JavaScript, with lines broken by hand using <tspan>; with <foreignObject>, the HTML rendering engine does that work on its own, every time the content changes, exactly as it would for any paragraph on an ordinary web page.
Classic trap
Content placed inside <foreignObject> must carry the HTML XML namespace, xmlns="http://www.w3.org/1999/xhtml", on its root element, usually a <div>. Without that declaration, some rendering engines, especially outside ordinary web browsers, refuse to show the content or silently drop it. A second trap shows up at export time: converting an SVG that contains a <foreignObject> into a PNG on a server often fails, because many conversion tools simply cannot interpret HTML nested inside SVG.
A real use case
Charting libraries such as D3.js lean on <foreignObject> to show tooltips with variable content, a legend that changes length depending on the data, or a label that must keep ordinary HTML formatting, bold text, links, line breaks, rather than being redrawn as plain <text>. A dashboard built in React or Vue, wrapping an SVG chart with interactive HTML widgets, benefits from the same trick: forms, buttons or search fields can live directly inside the drawing's coordinates, without juggling two separate positioning systems.
Frequently asked questions
Can an image or a form go inside <foreignObject>?
Yes, any valid HTML content fits there, including images, links, or form fields, as long as the XHTML namespace sits on the wrapping element.
Does <foreignObject> work in every browser?
Support is solid across modern web browsers, but gets noticeably shakier once the SVG leaves that context, for example in a PDF export, a server-side image conversion, or certain feed readers.
Does CSS applied to the HTML content behave normally?
Yes, the usual CSS rules, cascade, inheritance, media queries, apply without change to content placed inside <foreignObject>, since it stays HTML through and through: only its position follows the enclosing SVG's coordinates.