HTML in SVG
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.
- width
- Breite
- height
- Höhe
- x
- horizontale Position
- y
- vertikale Position
<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.
Was kann in einem foreignObject sitzen?
Technisch gesehen kann alles in einem foreignObject sitzen, was XML ist. Die Frage ist allerdings, was die Browser unterstützen.
<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.
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.
<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.