Inline SVG

From Svg wiki

Contents

Introduction

Inline SVG is SVG markup that is written directly into markup from a different XML dialect, typically XHTML. In theory, it is possible to write an XHTML document with self contained SVG graphics such as the circle in the following example. (In practice you may have to jump through some hoops to getting it working - see the sections that follow.)

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

    <svg xmlns="http://www.w3.org/2000/svg" width="300" height="200">
      <circle cx="150" cy="100" r="50" />
    </svg>

  </body>
</html>

Embedding SVG inline like this has several advantages over embedding SVG by reference using the HTML <object> tag, for example. When SVG is imbedded inline, it is part of the same document as the host XML. User agents have a significant amount of overhead for each document they render, so this can be an important saving. Having a unified DOM tree also removes the problems associated with scripting between documents. It also allows for a more dynamic layout, with graphics, text, and controls all placed together.

User Agent Support

User Agents supporting inline SVG out of the box include Firefox 1.5+, Opera 9+, Safari 3+ and Camino 1.0+. Inline SVG can also be supported in Internet Explorer 5.5+ if Adobe's SVG Viewer plug-in is installed, but it requires authors to jump through a few hoops. Welcome to a world where differences in doctype declaration, filename extensions or HTTP headers can make or break your content in one user agent or another - either when loaded from your server, or perhaps when you try testing it locally.

XHTML (XML) vs HTML

The biggest hurdle to authoring inline SVG is the distinction user agents make between XHTML (an XML dialect) and HTML (not an XML dialect). Internet Explorer doesn't really "do" XML. If you feed it some XHTML content and tell it that it's HTML (using a .htm/.html filename extension, or the text/html MIME type) then it may well render it as you intended. Note however that this is only because XHTML's syntax is similar enough to HTML's for Internet Explorer to think it is HTML. If you tell Internet Explorer that the same file contains XML (using a .xml/.xhtml filename extension, or the text/xml or application/xhtml+xml MIME type) it will simply display the file's source code. Contrast this with Mozilla Firefox's behaviour. Firefox will only recognise inline SVG when it is embedded in XML. In other words, if you tell the user agent that the file is XHTML, Mozilla will render the inline SVG, but if you tell it the file is HTML, Mozilla won't. This is because Mozilla uses a separate parser for HTML and XML, and only the XML parser is capable of doing the right thing with inline SVG markup.

So should you choose HTML or XHTML as the embedding markup for your inline SVG? Well if you want your content to be portable clearly the answer is XHTML. You can't get an XML requiring user agent like Mozilla to happily render HTML as XHTML because the HTML will almost certainly not be well formed XML. On the other hand you can get an HTML requiring user agent like Internet Explorer to render XHTML as HTML, so this is clearly the way to go.

Choosing a Filename Extension

So how do you get user agents to think your content is HTML/XHTML depending on what they can render? The conflicting requirements of Internet Explorer and Mozilla Firefox to have the embedding XHTML served as HTML/XML respectively, presents a fairly serious problem for the average content author. Internet Explorer requires a .htm/.html filename extension, and Mozilla Firefox requires a .xml/.xhtml filename extension. When loading and editing XHTML locally there is no way around this. Choose a filename extension based on which of the two user agents you will use for your development work. If you aim to make your embedded SVG portable, then Mozilla is probably the better choice for development. Since it will parse your XHTML as XML, it reports your errors if you make a mistake or if your content is not well-formed. Also, since Mozilla supports a smaller subset of SVG than Adobe SVG Viewer (ASV), most content that works in Mozilla will also work in ASV, though there are some exceptions (to see these exceptions, look at the current support tables for SVG Elements and DOM Methods; also see Cross-Platform Authoring).

Configuring your Webserver

Fortunately, for XHTML loaded from a webserver (where it matters), there is a solution to the HTML/XML conflict. By rewriting the HTTP headers the server sends with your content you can serve it as HTML by default, or XHTML if the user agent supports it. To do this in Apache put the following lines in your root .htaccess configuration file. The following code assumes that you chose to develop using Mozilla and gave your files the .xhtml filename extension. Using this filename extension also ensures that the HTML on your site that is not valid XHTML will not be served as HTML and break in user agents that require well formed XML (which might happen if you chose .htm or .html as the filename extension for the files containing inline SVG).

AddType text/html .xhtml
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_ACCEPT} application/xhtml\+xml
RewriteCond %{HTTP_ACCEPT} !application/xhtml\+xml\s*;\s*q=0
RewriteCond %{REQUEST_URI} \.xhtml$
RewriteCond %{THE_REQUEST} HTTP/1\.1
RewriteRule .* - [T=application/xhtml+xml]

Having done this you can confirm that your server is serving your documents with the desired type by checking the HTTP response headers in different user agents using a website such as web-sniffer.net.

The ASV Hack and Namespace Prefixes

Having understood and jumped through the hoops to lay a basis for inline SVG you're almost there. Now on to the actual content of the embedding XHTML file. There are two things that must be done for the inline SVG to render in IE+ASV. The first is a hack to tell Internet Explorer to use ASV to render the SVG tags. This is done by using the IMPORT processing instruction to associate ASV with the SVG "namespace". To do this is simply a case of adding the following two lines to the XHTML document.

<object id="AdobeSVG" classid="clsid:78156a80-c6a1-4bbf-8e6a-3cd390eeb4e2"></object>
<?import namespace="svg" implementation="#AdobeSVG"?>

The second thing that has to be done is to use a namespace prefix for all the SVG tags. Although redefining the default namespace as shown in the example at the top of this page conforms to the standards and works in Mozilla, IE+ASV doesn't support it. To be portable the example should be rewritten as in the following code.

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:svg="http://www.w3.org/2000/svg"
      xml:lang="en">
  <head>
    <title>SVG embedded inline in XHTML</title>
    <object id="AdobeSVG" classid="clsid:78156a80-c6a1-4bbf-8e6a-3cd390eeb4e2"></object>
    <?import namespace="svg" implementation="#AdobeSVG"?>
  </head>
  <body>
    <h1>SVG embedded inline in XHTML</h1>
    <svg:svg width="300" height="200">
      <svg:circle cx="150" cy="100" r="50" />
    </svg:svg>
  </body>
</html>

Other SVG Implementations

This technique also works as expected in Opera 9. However it does not appear to work in beta versions of Internet Explorer 7.

What if you want to use an SVG implementation other than Mozilla or ASV to render inline SVG? You'll have to investigate yourself. Please update this document to reflect your findings when you do.

Examples

Other things to add

  • The XML declaration (and DOCTYPE declarations?) seems to be required for ASV to work
  • Scripting: the XHTML DOM is different from the HTML DOM in FF (so things like .href won't work, so blog integration is a major problem).
  • Scripting: investigate the differences between using <svg:script> instead of <html:script>. when is one better than the other?