Farewell scene of the movie Casablanca

It was always intended that various “dialects” of XML could appear together in the same document: and MathML on the same HTML page, for example. This, however, leads to a problem: how can the browser distinguish between tags that use the same syntax?

For example, in <title> has a very specific use, and can only appear once. But in SVG, <title> is quite different, and may be used multiple times in the same document. If SVG and HTML are used together on the same page, how is the browser to make sense of the resulting confusion of tags?

In real life, if someone says “Paris”, you may be able to infer that they’re referring to a specific city. But computers cannot: without further context, they don’t know if you’re referring to Paris, France or Paris Texas.

In XML, the answer to this issue was namespaces. After the various edits detailed in the previous article, our SVG document still retains its namespace declarations:

<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 500 500">
    <!-- Remaining SVG code here  -->
</svg>

It may appear that the URL for the XML namespace might be used to “look up” information on the SVG specification. In fact, that’s not its purpose: the only role of the namespace is to create a unique identity for the svg element and its descendants, thus avoiding confusion with other markup.

The value of the attribute was set well before the publication of the SVG specification to avoid potential nameclashes with other specs. (Namespace values for every specification must always start with http:, but are always interpreted by the browser as a string, rather than an active URL.)

Without the xmlns namespace, most browsers and editors will not render an SVG drawing, although there are exceptions.

XLink

XML documents were not originally intended to link to each other; to create links, we must “borrow” the href attribute from HTML. However, we encounter the same potential problem of confusing HTML and SVG markup, so we must extend the original SVG namespace with a prefix for links:

<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink">

As before, it is convention to supply the URL to the specification as the value, although it isn’t used to “look up” anything.

Once this is created, links can be used in the context of SVG just like they can in HTML, primarily for two purposes:

  1. We can create links to other documents in the SVG; frequently, these are wrapped around paths or other elements to make them interactive:
    <a xlink:href="http://travelalberta.ca">
        <path d"…" />
    </a>
  2. We can also create references to other fragments, just as id values can be used to create anchor links in HTML. This is often applied in <use> elements in order to reference symbols. In the example below, an SVG icon is created by referencing a <symbol> defined further down the page, in a separate SVG element. (Note that the namespaces for both <svg> elements have been dropped, as we can get away with doing so in this specific case).
    <svg class="icon" aria-label="CodePen" width="50" height="50">
            <title>Codepen</title>
            <use xlink:href="#codepen" />
        </svg>
    </a>
    …
    <svg style="display: none;">
        <symbol id="codepen" viewBox="0 0 50 50">
            <path d="…"/>
        </symbol>
    </svg>

Many SVG visual editors insert attributes and elements in their own namespaces. Inkscape tends to be particularly egregious in this regard. A typical example:

xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="0.91 r13725"
sodipodi:docname="drawing.svg">

These additions won’t affect the rendering of the SVG, and in most cases they should be removed from the final production version when the file is optimized to save on file size.

Implications for CSS

At a practical level, namespaces aren’t terribly relevant for most applications of CSS to SVG: if you want to affect a path element with CSS, you can use standard CSS selectors to reach it:

path#outline { stroke-thickness: 5px; }

However, it is possible to specify a namespace for CSS to confine selectors.

Implications for JavaScript

The nature of namespaces also means that selection and creation may change for in relationship to SVG: rather than document.createElement, we can use document.createElementNS. I’ll have much more to say about these changes in future JavaScript for SVG articles.

SVG 2

In the SVG 2 specification, href finally becomes a “first class citizen”, eliminating the need for namespacing and prefixes. This means that in the near future we will be able to write a link in SVG as we would in an HTML document:

<a href="http://travelalberta.ca">
    <path d"…" />
</a>

However, we will have to wait for broad support of SVG 2 in browsers before implementing these changes.

I’d like to thank Amelia Bellamy-Royds for her help as an editor on this article.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.