Using SVG on the Web

If you are able to ignore Internet Explorer, all the other major browser can render SVG content. Recently, while writing previous posts and webapps, I discovered several quirks that may cause browsers to fail to render SVG content consistently.

Including SVG inline in the document.

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Using SVG inline in an XHTML document</title>
  </head>
  <body>
    <h1>Using SVG inline in an XHTML document</h1>

    <svg xmlns="http://www.w3.org/2000/svg" width="250" height="250"
         style="border: 1px solid black">
      <circle fill="rgb(250, 160, 20)"
              cx="100" cy="50" r="80" />
      <rect fill="rgb(20, 250, 20)" fill-opacity="0.6"
            x="35" y="85" width="180" height="85" />
    </svg>

  </body>
</html>

View this example in your browser.

Inline SVG is an attractive option because it doesn’t require an external file. Unfortunately, inline SVG has one significant problem: authors are forced to use XHTML and the application/xhtml+xml MIME type, instead of standard HTML and the text/html MIME type. XHTML is not a very forgiving language, and one I would generally discourage. Depending on authoring tools and other content on the page, producing valid XML may be difficult. Even more problematic is that Internet Explorer will refuse to display the page at all; there is no graceful fallback for the majority browser. Finally, syndicating SVG in feeds will often cause the SVG to be stripped as it is syndicated.

I used inline SVG for my Mozilla compiler warnings front end, because I don’t care about Internet Explorer users in that application. But it has very limited usefulness in general.

Referencing external SVG content

At first glance, it might seem that you could reference an SVG document using the HTML &lt:img> element., but this is not the case. SVG images are complete sub-documents. They have their own script context and can script themselves. They can also load additional sub-documents such as images. Because of this, browsers force authors to embed SVG images using <object> or <iframe>.

Embedding SVG with <object>

The <object> element is the generic HTML mechanism for embedding external content. It can be used just like an <iframe> for external HTML document. It can be used to embed plugin-rendered content such as Flash, and it can be used to embed SVG:

<object type="image/svg+xml"
        data="http://benjamin.smedbergs.us/blog/wp-content/uploads/2008/12/svg-document1.svg"
        width="250" height="250">
  Alternate markup here. If you see this, your browser may not support SVG, or a content aggregator may have stripped the object element.
</object>

Alternate markup here. If you see this, your browser may not support SVG, or a content aggregator may have stripped the object element.

The object element is the best choice in most situations. All browsers including Internet Explorer will display the fallback content if they don’t know how to display SVG or if the image won’t load. Using the object element, authors can even pass parameters to the SVG document.

Embedding SVG with <iframe>

It is also possible to include SVG content using the <iframe> element.

<iframe width="350" height="250"
        src="http://benjamin.smedbergs.us/blog/wp-content/uploads/2008/12/svg-document1.svg">
  Alternate markup here. If you see this, your browser might not support iframes, or a content aggregator might have stripped the iframe element.
</iframe>

There are minor but important differences using iframe rather than object to display SVG: Internet explorer will load the iframe but choke on the SVG content. The user won’t skip back to the fallback content within the <iframe>element, and in some cases the user may see a download prompt for the SVG document. But many content sanitizers such as those found in feed aggregators will allow <iframe> through while rejecting <object> And finally, iframes have a border by default. You can remove this border using CSS.

Use this MIME type: image/svg+xml

The correct MIME type for SVG content is image/svg+xml. Firefox will accept application/svg+xml but Safari will not!

Specify image dimensions

The author should know the image dimensions in advance. If you don’t specify the width and height in the <object> or <iframe> element, browsers will initially size the object at 300×150 pixels, and then their behavior will diverge:

<object> <iframe>

Firefox Resize to the image intrinsic size, once loaded Scroll overflow content

Opera

Safari Crop overflow content

Example

Your browser doesn’t appear to support SVG, or a content aggregator has stripped the <object> tag.


Don’t use rgba() colors in SVG

The CSS3 specification allows for any color to be specified with transparency using rgba syntax. Many web browsers support RGBA colors for HTML content, but only Firefox supports them for SVG content. Instead of using rgba colors, use the SVG properties fill-opacity and stroke-opacity for maximum portability.

<svg xmlns="http://www.w3.org/2000/svg" width="500" height="100">
  <circle fill="rgb(180, 180, 250)"
          cx="100" cy="20" r="85" />

  <text x="10" y="45" font-size="40" fill="rgba(0, 0, 0, 0.3)">rgba transparent text?</text>
  <text x="10" y="95" font-size="40" fill="black" fill-opacity="0.3">use fill-opacity instead!</text>
</svg>

SVG using rgba colors and fill-opacity

Atom Feed for Comments 16 Responses to “Using SVG on the Web”

  1. Daniel Glazman Says:

    There is an extra option that works fine for HTML documents : include a light JS script that will at load time detect all svg-like elements in the plain html instance and replace it by the the same DOM subtree in the correct SVG namespace. Many, many people use that hack. Granted, it’s not nice. But at least it degrades gracefully in IE.

  2. mawrya Says:

    Thanks for taking the time to post your findings. Developing internal company web apps leaves me with the luxury of ignoring whatever browsers I want so inline SVG has been used extensively with Firefox to create some pretty jaw-dropping interactive reports. Having always wanted to get some of the stuff working in Safari, I was happy to stumble across your post as it seems to be a great jump-start. Thanks.

  3. mawrya Says:

    I am also curious: what do you mean when you say XHTML is not a very forgiving language? Isn’t it just another XML language like SVG? Thanks again.

  4. Cameron McCormack Says:

    > Many web browsers support RGBA colors for HTML content, but only Firefox supports them for SVG content.

    Opera 10 alpha does support RGBA colours in SVG content.

  5. Anonymous Says:

    Instead of &lt: you probably meant to write a semicolon there…

    An XML-based system would have caught this error, you know ;p. (And no, it would not break your page, it would refuse to submit it before you correct the error.)

  6. Benjamin Smedberg Says:

    Anonymous: I don’t know what “refuse to submit” means… WordPress doesn’t do XML validation during editing. A simple typing error would cause my post to be unreadable in browsers.

  7. Frédéric "LpSolit" Buclin Says:

    Benjamin,

    Do you think SVG would be a good alternative to draw graphs in Bugzilla? Any idea if IE7 supports SVG natively? Or at least if there is a plugin to display SVG content?

  8. Benjamin Smedberg Says:

    LpSolit: no, I don’t think SVG is a good tool for bugzilla graphs. I think you should consider using a cross-browser graphing library such as http://www.liquidx.net/plotkit/ which uses canvas on browsers and a VML shim library to support IE.

  9. Frédéric "LpSolit" Buclin Says:

    The reason is because IE doesn’t support SVG or because SVG is not suitable to display graphs?

  10. Benjamin Smedberg Says:

    IE doesn’t support SVG natively, and the only ActiveX control that I know of (the Adobe one) was discontinued.

  11. Robert O'Callahan Says:

    HTML IMG elements should support SVG images. We plan to add that in Gecko 1.9.2.

  12. Merry Christmas (and a few links) ~ intangiblestyle Says:

    [...] Benjamin Smedberg takes a look at a crop of cross-browser issues with using SVG on the web. [...]

  13. Max Design - standards based web design, development and training » Some links for light reading (6/1/09) Says:

    [...] Using SVG on the Web [...]

  14. Lachlan Hardy Says:

    Frederic: You might also want to look at Raphaël. It is JavaScript API for drawing vector graphics cross-browser – it uses SVG in supporting browsers and VML in IE. It is suitable for graphing and even has two emerging charting libraries built on top of it: SimpleGraph and TufteGraph.

  15. Frédéric "LpSolit" Buclin Says:

    Lachlan: I would prefer a JS-less way to display graphs. There are still some users of Bugzilla who don’t have JS enabled.

  16. Benjamin Smedberg Says:

    A Belorussian translation of this article has been posted. A big shout-out to Martha Ruszkowski for doing that work!

Leave a Reply