Joe Hewitt

SVG and XHTML: Like Oil and Water

For the last few days I have been experimenting with SVG in Firefox. I would like to start using SVG on my blog, both for decorative and functional purposes, so my experiments revolved around ways to mix SVG with XHTML. Unfortunately, what I've learned is very disappointing.

After a couple days of working with SVG, I have the feeling that nobody on the SVG working group gave any thought to how vector graphics could make interactive web GUIs better. It seems they were more concerned with lions, and tigers, and bars (oh my). In other words, SVG was designed to be primarily an image file format; a vector alternative to PNGs and JPGs.

That's a shame, because SVG could be perfect as a means of escaping the rectangular tyranny of HTML and CSS. Think of the fun of being able to tilt photographs, fill text with gradients, or create circular buttons. Unfortunately, if you try to achieve these effects using SVG and XHTML together, you won't be having any fun. You will be too busy doing geometry calculations by hand (which the SVG engine should be doing for you).

All Your Vector Are Belong To Us

The first frustration I experienced with SVG is that it forces me to place all vector elements inside of an <svg> element. You cannot, for example, freely mix an <svg:circle> with HTML tags.

Why does this restriction exist? My guess is because SVG's creators were overly concerned with the need for custom coordinate systems. The <svg> element can be used to declare a new coordinate system in which 1 unit of SVG length may be different from 1 pixel. That's a neat feature, but if SVG is going to play nice with XHTML, then it needs to adapt to the XHTML/CSS coordinate system, not insist on having its own.

Go Against the Flow

In GUI languages (like HTML, XUL, XAML, or Laszlo) we have these things called layout algorithms, which take care of measuring things, figuring how how much space they consume, and automatically flowing the surrounding elements to fit. In SVG, there is no such layout intelligence.

If you want to embed SVG in the flow of HTML, have a #2 pencil and paper ready, because you're going to need to crunch a lot of geometry first. SVG expects you to manually position and size everything. As a result, mixing SVG with XHTML is extremely tedious.

Here is an example of simple markup that I thought I would be able to write:

<html:p>Look how lovely and round: <svg:circle r="40px" fill="blue"/></html:p>

You would expect this source to produce the result you see to your right. Unfortunately, this is not a legal use of SVG. The circle must be contained within an <svg> element. Let's try that:

<html:p>Look how lovely and round:
       <svg:svg>
        <svg:circle r="40px" fill="blue"/>
       </svg:svg>
</html:p>

That's legal, but look what it renders - only a quarter of the circle, and the HTML text is missing. SVG isn't thoughtful enough to measure that circle for you and flow it with the text. It insists that you declare the size of the SVG viewport, and then it expects you to explicitly position the circle within that space, like so:

<html:p>Look how lovely and round: 
    <svg:svg width="80" height="80">
        <svg:circle r="40" cx="40" cy="40" fill="blue"/>
    </svg:svg>
</html:p>

This code produces the expected result, but... but.... yuck. Look how much more complicated that is than my intuitive first attempt.

Look but Don't Touch

Another major problem with the <svg> element is that it eats mouse events for breakfast.

If you have an <svg> graphic overlapping some XHTML, odds are that there will be a lot of empty space not occupied by vectors. Imagine that your graphic overlaps some HTML text, and you wanted to select some text that is clearly visible under the empty space in the graphic. As they say back in Jersey, fuggedaboutit. The <svg> element will be the target of all mouse events and nothing will happen when you try to click on the text.

If SVG elements could be freely mixed with XHTML like I described above, this would not be a problem.

Robots Love It

So, it seems that SVG suffers from the same disease as Microsoft's XAML - it is not meant to be typed in by humans. It is meant to be created by visual tools and scripts. This is too bad, because an awful lot of people still write GUI code by hand. The end result is that you won't see SVG doing much to help authors of themes (like Firefox's own), web widgets, or Ajax applications any time soon.