SVG foreignObject – HTML in SVG einsetzen

<foreignObject> setzt Elemente aus anderen XML-Namensräumen in ein SVG. Mit einem foreignObject-Element kann der Browser Grafik oder Text aus HTML innerhalb von SVG rendern.

HTML and MathML in SVG

Text dank foreignObject automatisch umbrechen

Der nahe liegende Einsatz für foreign-Object-Elemente ist Text, denn SVG hat zwar einen weitreichenden Satz von Text-Attributen und legt sich für die Typografie ins Zeug, aber was dem Text fehlt, ist der automatische Zeilenumbruch.

Ein Foreign Object braucht eine Höhe und Breite sowie eine Position im SVG.

HTML in SVG
HTML Text in SVG
<foreignObject x="46" y="500" width="1200" height="900">
	<body xmlns="http://www.w3.org/1999/xhtml" style="font-family: Amadeus; font-size: 110px">
		<p>Je schneller du dich bewegst, desto schwerer wirst du. Gott sei Dank ist das nicht andersrum.</p>
	</body>
</foreignObject>

Der HTML-Einschluss via foreignObject erspart nicht nur die Umsetzung in tspan-Zeilen, sondern auch die Berechnung des Zeilenabstands.

Formulare in SVG

SVG unterstützt keine HTML-Formular-Elemente. Mit <foreignObject> kann man jedoch <input>, <select> oder <textarea> einbinden.

Das SVG-Element kann nicht mit HTML img eingesetzt werden, sondern muss mit iframe oder object eingebettet werden, damit die Formular-Elemente funktionieren.

<svg width="220" height="100" xmlns="http://www.w3.org/2000/svg">
	<foreignObject x="10" y="10" width="220" height="160">
		<body id="body" xmlns="http://www.w3.org/1999/xhtml">
			<input type="text" placeholder="Dein Text hier …" />
			Deine Farbe
			<select id="select" name="select">
				<option value="#fff">weiss</option>
				<option value="hsl(220,60%,80%)">blau</option>
				<option value="hsl(40,80%,80%)">gelb</option>
			</select>
<script>
document.querySelector("#select").addEventListener("input", function () {
	document.querySelector("#body").style = "background: " + this.value
})
</script>
    </body>
  </foreignObject>
</svg>

MathML in SVG mit foreignObject

Technisch gesehen kann alles in einem foreignObject sitzen, was XML ist. Die Frage ist allerdings, was die Browser unterstützen.

k= n m a(k)
<svg id="svg1" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
<rect width="300" height="200" fill="hsl(190,50%,50%)"/>
	<foreignObject x="50" y="50" width="200" height="200">
		<math xmlns="http://www.w3.org/1998/Math/MathML" display="block" style="font-size:2em;color:white">
		  <munderover>
			<mo>∑</mo>
			<mrow> <mi>k</mi><mo>=</mo> <mn>n</mn> </mrow>
			<mi>m</mi>
		  </munderover>
		   <mi>a(k)</mi>
		</math>
	</foreignObject>
</svg>

Safari unter MacOS und Firefox unterstützen MathML direkt, Chrome unterstützt MathML erst seit Version 109 (Jan 2023).

CSS in SVG schmuggeln

SVG hat Lücken – so z.B. die konischen Verläufe –, die in CSS aber bereits von allen modernen Browsern unterstützt werden.

0.6 0.6 0.6 0.6 0.5 0.4 0.3 0.2 0.1 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9
Eine Anwendung für einen konischen Verlauf: die zweidimensionale Darstellung des CIE XY-Farbraums im Farbmanagement

Um einen konischen Verlauf in einer SVG-Form unterzubringen, sitzt ein HTML-div-Element im foreignObject. Im einfachsten Fall kann eine Tortengrafik in SVG mit wenigen Zeilen umgesetzt werden.

torte
SVG-Tortengrafik mit konischem Verlauf
<svg width="100%" height="100%" viewBox="0 0 400 400">
	<clipPath id="clip">
		<circle cx="200" cy="200" r="150"/>
	</clipPath>
	<style>
		.torte {
		    width:100%;
		    height:100%;
		    background-image: conic-gradient(red 0%, red 20%, lightslategray 20%, lightslategray 30%, pink 30%, pink 50%, yellow 50%, yellow 75%, mediumaquamarine 75%, mediumaquamarine 100%)}
	</style>
	<rect width="400" height="400" fill="cyan"/>
	<foreignObject clip-path="url(#clip)" x="50" y="50" width="300" height="300">
		<div class="torte"></div>
	</foreignObject>
</svg>

Anstelle des einfachen circle-Elements könnte jede beliebige SVG-Form (path) stehen.

Ohne Text wird das foreignObject nur als inline-SVG korrekt dargestellt.

Suchen auf mediaevent.de