How to Render HTML Inside SVG with foreignObject
The Scalable Vector Graphics (SVG) specification allows developers to
embed standard HTML elements directly into vector graphics using the
<foreignObject> element. This article explains how
<foreignObject> functions, provides a practical code
implementation, details the required XML namespaces, and highlights
crucial layout rules and limitations when blending HTML and CSS inside
an SVG coordinate system.
Understanding the
<foreignObject> Element
The <foreignObject> element acts as a bridge
between the SVG document object model and external XML namespaces, most
commonly XHTML. It creates a rectangular region within the SVG viewport
where standard HTML markup, such as <div>,
<p>, <span>, form inputs, or
complex styled components, can be rendered and styled using regular
CSS.
Basic Syntax and Implementation
To render HTML inside SVG, place the
<foreignObject> element inside the
<svg> container. Within the
<foreignObject>, include your HTML elements and
define the XHTML namespace
(xmlns="http://www.w3.org/1999/xhtml").
<svg width="400" height="300" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg">
<!-- Standard SVG Background Shape -->
<rect x="0" y="0" width="400" height="300" fill="#f0f4f8" rx="8" />
<!-- foreignObject Container -->
<foreignObject x="20" y="20" width="360" height="260">
<!-- Standard HTML Content -->
<div xmlns="http://www.w3.org/1999/xhtml" class="html-container">
<h2>Embedded HTML in SVG</h2>
<p>This paragraph wraps automatically based on the width of the container.</p>
<button type="button">Interactive Button</button>
</div>
</foreignObject>
</svg>Essential Attributes
The <foreignObject> element requires explicit
spatial dimensions to display content properly:
x: The horizontal position where the container begins in the SVG coordinate system.y: The vertical position where the container begins in the SVG coordinate system.width: The allocated width for the HTML rendering box. If omitted or set to0, the HTML content will not render.height: The allocated height for the HTML rendering box.
Styling Embedded HTML
HTML elements inside <foreignObject> can be styled
using external stylesheets, inline styles, or <style>
blocks within the SVG or the main document.
<style>
.html-container {
font-family: Arial, sans-serif;
color: #333;
padding: 12px;
background: white;
border-radius: 6px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
</style>Key Considerations and Limitations
- Namespace Declaration: Always declare
xmlns="http://www.w3.org/1999/xhtml"on the top-level HTML element inside<foreignObject>to ensure the browser parser correctly recognizes the content as HTML. - Explicit Sizing: HTML text wrapping relies on the
widthattribute of<foreignObject>. Unlike native HTML<div>elements,<foreignObject>will not automatically expand to fit its contents if SVG dimensions are constrained. - Canvas Export Limitations: If you convert an SVG
containing a
<foreignObject>into an HTML5<canvas>usingdrawImage(), modern browsers will often block the action or taint the canvas due to security constraints. - Transformation Support: HTML elements inside
<foreignObject>respect SVG transformations such asrotate(),scale(), andtranslate()applied to the parent<foreignObject>or containing<g>groups.