[whatwg] Including HTML more directly into SVG

Ian Hickson ian at hixie.ch
Fri Dec 28 20:59:40 PST 2012

On Mon, 10 Sep 2012, Tab Atkins Jr. wrote:
> 1. Check out <http://www.xanthir.com/etc/railroad-diagrams/example.html>.
> See all those boxes full of text in the diagrams?  Looks simple, right?  
> Just a box filled with text, with a border and background set on it.  
> Wrong!  SVG doesn't have any primitives like that.  Instead, you have to 
> position the text, measure its dimensions (or, like I've done, guess at 
> the dimensions based on the font-size and such), then create and 
> position an *independent* <rect> element behind it, so that it *looks* 
> like there's a box with text inside of it.

Well, you can just put the text in a <foreignObject> with a <div>, and 
style that.

Your bigger problem is going to be positioning the lines on the other side 
of the <rect>/<foreignObject>.

> This would be a lot easier if I could somehow invoke the CSS box model 
> inside of SVG, but the <text> element doesn't allow that.

That's what <foreignObject> is for.

> Closely related to this, SVG doesn't do automatic linebreaking at all. 
> If you want text to break, you have to do it manually, not only 
> determining the break points but also manually setting the line-spacing 
> separation for each individual line.  Again, it would be cool to invoke 
> the CSS box model here, so we get full-power inline layout.

<foreignObject> does that too.

> [...] there is an a11y tool that lets low-vision users interact better 
> with SVG diagrams.  They can print out an SVG, attach it over a 
> pressure-sensitive touchpad, then bring up the diagram on the screen as 
> well.  Using the touchpad, they can then zoom/pan the SVG, or even ask 
> the computer to read out text at the location they've pressed.  
> Unfortunately, the textual semantics in SVG are pretty impoverished 
> right now; there *aren't* any semantics, besides "here is text".  It 
> seems pretty obvious that you'd sometimes want to, say, emphasize a span 
> of text inside a larger text block in a diagram, but right now the only 
> way to do that is by using <tspan style="font-style:italic;> and hoping 
> that the reader supports enough CSS to guess that italicized text should 
> be emphasized.

How common is it for text in a diagram to be emphasised to the point where 
you definitely need a clear indication in a speech-synthesis rendering 
done in conjunction with a visual display? It seems like it'd be rare 
enough that the mere visual indication of italics would make it pretty 
obvious to the user what was going on...

> It would be pretty nice if you could use <em> or the other textual HTML 
> elements here, for the same reason it's nice to use them in HTML rather 
> than relying on visual presentation.

In the cases where you need this, isn't <foreignObject> enough?

> 3. Related to the above, it seems useful to be able to embed "special" 
> elements like <input type=date>, <video>, or <details> into SVG, for the 
> same reasons you'd include them in HTML.

Or MathML, indeed. Again, this seems reasonably easy with <foreignObject>.

Which you point out:

> Right now, all three of the above *could* be done by using the 
> <foreignContent> element.

Right. :-)

> This is a horrible solution, though.  To use <foreignContent>, you need 
> to specify a width and height (and we're back to measuring or guessing 
> at the dimensions...) and specify a namespace.  This is a lot of weight 
> to put into a document when all you want to do is include some simple 
> text.

You don't have to specify a namespace in text/html, but agreed about the 
width and height. Even worse, IMHO, is having to use the name 
"foreignObject", which is highly unwieldy. It would definitely be nice to 
have an element in SVG with a short name that introduced an HTML context 
in text/html, and that was shrink-wrap enabled. Even better would then to 
be able to reference the dimensions from other elements, so that you 
wouldn't have to measure the element anyway (e.g. to position the line in 
your example above).

I would recommend calling this element <svg:div>, for what it's worth. (I 
had an <xbl:div> for similar reasons). But any short name would do, e.g. 
<html>, or <block>, or <flow>, or whatever.

> Another solution could be SVG inventing their own elements for these
> kinds of things.

That doesn't seem like a good plan, as you point out.

> My preferred solution is to simply include HTML directly into SVG.

I presume you don't mean duplicating the elements in both namespaces, but 
making the text/html parser detect which elements are where?

> This solves #1 perfectly - all that needs to be done is to specify the 
> SVG rendering model in terms of the CSS box model (it's simple, just a 
> slight diff on position:absolute), then <span> or <p> works great.

I'm not entirely convinced that that makes sense, but I'll leave that to 
www-style and www-svg to figure out.

> This requires some minor parsing changes in HTML.

I don't think they are minor in consequences, as others (e.g. Elliott 
Sprehn) discussed in this thread (not quoted here for brevity).

However, even if they were, I don't see why this would be better than 
introducing a better version of <foreignObject> that shrink-wraps. Doing 
that wouldn't require any changes to CSS or SVG or HTML except adding a 
single new element to SVG with a simple-ish processing model, and a minor 
change to the HTML parser.

> Specifically, in 
> http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#parsing-main-inforeign 
> (section "The rules for parsing tokens in foreign content"), 
> the rule that makes any HTML element pop the stack of open elements 
> until it closes the SVG element would need to be removed.  I'm aware 
> that this was put in place to avoid breaking a few pages that, seemingly 
> for no reason, include an <svg> tag at the start of their page with no 
> matching </svg>, as including the HTML directly in the <svg> element 
> would suppress their rendering.  However, with my suggested change, 
> these pages would continue working, albeit probably with a slightly 
> different rendering.

Dramatically different rendering. The entire remainder of the page would 
end up stacked on top of itself, if I'm understanding what you're 
describing correctly (treat all the children of <svg> as pos:abs).

> If this is unacceptable, it's acceptable to me to require a small, 
> simple wrapper element that accomplishes the same thing as 
> <foreignContent>, but automatically places its contents in the HTML 
> namespace and auto-sizes itself, and have the parser key off of that. 
> This should be avoided if possible, though, as it's annoying for authors 
> with no direct benefit to them.

I think that's a far simpler and clearer solution, both for specs, 
implementors, and most importantly, authors.

For context, consider word processing programs like Pages or Word. They 
tend to have two modes -- one where there is flow text with floating or 
overlapping objects (SVG blobs, in our world), and one where everything is 
positioned and if you want text you put in a text box (<foreignObject>, in 
our world). I don't know of any markup language or graphics system where 
paragraphs are conceptual siblings with paths and shapes.

Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

More information about the whatwg mailing list