SVG Document Structure

Document Structure, Grouping, and Reusability

by Rob Levin

Overview

A look at how to achieve reusabability with SVG's semantic grouping and referencing elements. We additionally look at SVG's root element too.

SVG Document Structure

For most web developers, SVG (or Scalable Vector Graphics), should bring some familiarity in terms of syntax. This is due to the fact, that SVG is a dialect of XML and quite similar to HTML. However, many “SVG noobs” hit a stumbling block with a couple of concepts that are unique to SVG. My advice to folks new to SVG, is to push through these challenges, since the ROI that SVG brings is well worth the effort. With that said, I hope that this article clarifies one of the more challenging areas…SVG Document Structure.

Delving in to this area of SVG will lead us to examine the following:

SVGs Root Element

SVG's root element can be a beast of an element to tame for noobs, and attempting to address certain available attributes (like viewBox and preserveAspectRatio for example), will take you you directly in to one of the most difficult to grok areas of SVG…coordinate systems. As such, we'll purposely avoid these, and, only look at the “easy-peasy” attributes that concern us here (we'll tackle the harder stuff in future articles!)

With the disclaimer that we're not going to worry about scaling or responsive web design (for the time being), the simplest use of the root element might look as follows:

<svg width="100" height="100" xmlns:svg="http://www.w3.org/2000/svg">
    ...
</svg>

Let's take these attributes one at a time and also point out some relevant take aways:

So there you have it, about the easiest explanation I could think of for how SVG's root element works. We'll get in to the “other half of the story” when we look at SVG Coordinate Systems in a future article. Also, if you're concerned about how this all works in a reponsive design work-flow, please don't fret over the fact that we have a fixed dimension SVG (at least not for the time-being)–we're trying to keep things simple and approachable, so please trust me; we'll get in to how to implement responsive SVGs in a couple articles from now ☺

Grouping Elements

Let's now take a look at how SVG does grouping and how elements can be instantiated for reuse. We'll start with the <g> element.

Grouping With The <g> Element

The <g> element acts as a container element that allows you to, well, group related elements. If you have any experience with graphical software packages like Adobe Illustrator, Omnigraffle, Keynote, etc., you've like used similar functionality to group like-elements that you want to be able to manipulate, or move, together in one broad sweep. Conceptually, the goal is the same: to group graphical elements that make more sense to be manipulated together.

Accessibility and Groups

The specification provides that the <g> grouping element used in conjunction with the description element <desc>, and the title element <title>:

provide information about document structure and semantics. Documents that are rich in structure may be rendered graphically, as speech, or as braille, and thus promote accessibility

So, in addition to convenience, you should keep this in mind, as you logically and semantically structure your SVG documents.

Group elements can be nested and given an id attribute (providing an id is useful if you wish to later animate that group, or, if you wish to reference it later).

Reuse and Definition Elements

The <def> is used for defining reusable definitions for later referencing. They are not in the render tree, and, conceptually act as if you've defined <g style="display: none">. They too, can provide semantic meaning to the document, providing that the “intent” is to reuse the definition at a later point in the document. Definitions can be wrapped around groups if so desired.

Symbols

The <symbol> element is interesting in that it behaves as though you've defined <def><g>...</g></def> (in a way), but are not at all a part of the render tree, have their own viewBox (a topic we're not intending to discuss here), and serve as reusable templates for later use.

Again, the specification likely says it best when trying to understand the differences between the symbol and group elements:

The key distinctions between a ‘symbol’ and a ‘g’ are:

A ‘symbol’ element itself is not rendered. Only instances of a ‘symbol’ element (i.e., a reference to a ‘symbol’ by a ‘use’ element) are rendered. A ‘symbol’ element has attributes ‘viewBox’ and ‘preserveAspectRatio’ which allow a ‘symbol’ to scale-to-fit within a rectangular viewport defined by the referencing ‘use’ element.

Referencing Elements

Reusable definitions defined with either: <def><g>, or, <symbol>... can later be referenced via:

Using <use>

Using the <use> element is quite simple:

  1. Give your definition element an id attribute
  2. Simple reference that id

If the definition being referenced is defined on the page or within the same SVG document, you can do something like:

<use xlink:href="#dog" />

But you can also reference externally defined definitions (ex. an SVG definitions file) like:

<use xlink:href=“path/to#dog" />

However, the later technique does require an IE shim. Read about that in my guest post on css-tricks 5 Gotchas You’re Gonna Face Getting Inline SVG Into Production.

Let's next take a look at how this all works from both sides (the definition and the reference)…

Putting It All Together

Let's start with an example of referencing an SVG linearGradient effect via CSS:

<svg>
    <defs>
        <linearGradient id=“my_gradient"> ... </linearGradient>
    </defs>
    <circle style=“fill:url(#my_gradient) ... />
    <rect style=“fill:url(#my_gradient) ... />
</svg>

In the above code snippet, we've defined a linear gradient in a <def>, provided an id of my_gradient, and then simply referenced that id from within the fill:url style rule.

The other way we can reference a reusable definition–via the use xlink:href mechanism might look as follows:

<svg>
    <symbol id="my_symbol"> ... </symbol> 
    <g><use xlink:href="#my_symbol" ... /></g>
</svg>

It should be fairly straight-forward, but we're simply defining a symbol, giving it an id, and the referencing that id from the “using” <use> element. Note, that, although we've demonstrated using a <symbol> definition here, we may have also elected to use something like <def><g id="my_group" ... should we have preferred to do so.

Conclusion

Hopefully, you found this article on SVG's Document Structure concepts approachable and helpful. If not, please do leave a comment and I'll do my best to provide clarification. Otherwise, best of luck in your SVG adventures!

Comments