< previous

next >

Wireframes with SVG

by Manuel Strehl

Filed under

Keywords: ,

The SVG train is starting to gain momentum. Internet Explorer as the last of the major browsers is lacking support for displaying SVG images, but its developers gave a hint, that this may change with IE 9.

This article intends to demonstrate a different use of the XML-based vector graphics format. I will show you today how to use SVG to create wireframes out of a new website design and the advantages of this method over the classical Photoshop → text editor → browser approach. The article is not about using SVG inside web pages, although I will briefly touch this topic, but about designing them before their conversion to HTML.

In the remaining part, as a synonym for an SVG enabled drawing program, I will talk about Inkscape, an open source vector graphics program included in most current Linux desktop distributions and available for Windows and Mac. If you own a copy of Adobe Illustrator or CorelDraw, itʼs perfectly fine and straight-forward to go with that, since they also support SVG. A missing part there, however, is the embedded XML editor that I will mention below.

The Artistʼs Perspective

Consider a customer ordering a new website. The first thing happening usually is the designer firing up Photoshop and creating a draft of the siteʼs look. Afterwards the web developer looks at the draft and tells the designer, what could or could not be done in the HTML/CSS/JavaScript trinity. Then the wireframe enters the next iteration round. Meanwhile, the developer creates a prototype of the siteʼs functionality in the hope that lateron it can be included in the designerʼs concept easily.

Using SVG instead of PSD files doesnʼt help with the need for communication between designer and developer. But it has a very immediate advantage:

  1. SVG files can be viewed directly in the browser.

This is not to be underestimated. It is highly improbable, that the designer works with something as uncomfortable as a GIF, PNG or JPEG. That means, every time a tiny bit of the original draft is changed, the file has to be converted to either format before being viewable in a browser. By using SVG a preview of the new website is as simple as hitting Ctrl+S in Inkscape and F5 in your SVG enabled browser.

However, using vector graphics for a website mockup is not always simple. If the page design relies heavily on pixel art or pictures, working with lines and boxes tends to get a bit rough. Nevertheless many designs are merely a combination of geometric figures, sometimes with gradients or patterns, and for those you will find vectors much more comfortable than pixels. SVG also offers an image element to embed other images, raster graphics included. This, together with its masking and filter possibilities, can recreate many of Photoshopʼs effects. And then, changing the header image in a design is as simple as changing the URL reference on the image tag.

The advantage of vector graphics becomes apparent, too, if your interface elements consist mostly of icons of some sort. Since good icons are delivered as vector images (as long as they are not especially optimized for tiny sizes), you will find it dead easy to embed, adapt and scale such icons to fit your design.

Taking Advantage from XML

Weʼre switching back now from the designerʼs workbench to what can be done with a ready-to-work-with design template in the hands of a web developer.

As said above, SVG is an XML language. That has the nice side effect, that SVG files are plain text files. If your workflow involves some kind of version control system, you can easily check for differences between two different states of a wireframe from your terminal and have good chances to understand, what is going on. No need for Photoshop on both the designerʼs and the developerʼs machine… That said, SVG is also an open standard. You only need any program that supports the features used in a particular SVG file, and the file will look all the same.

Also, since SVG is XML, you can use your whole XML toolbox with the wireframe. Imagine, the draft lies on your testing server and youʼre familiar with, say, Pythonʼs XML modules. Then it is a very simple task to read the design draft, apply some DOM manipulation to it and output the result to your testing browser instead of the original SVG file.

  1. SVG is a plain text format and an open XML language.

An Example Setup

To give you a grip on what Iʼm talking about, Iʼll sketch a short example SVG file. This could be used as a template by both the designer and the developer.

<svg version="1.1"
     xmlns="http://www.w3.org/2000/svg"
     width="1000px" height="1000px">
  <title>Website Template</title>
  <defs/>
  <g id="page">
    <g id="header">
      <rect x="0" y="0"
            width="1000" height="120"
            fill="green" />
      <text x="20" y="70"
            style="font: bold 3em Helvetica,Arial,sans-serif;">
        A Heading
      </text>
    </g>
    <g id="navigation">

    </g>
    <g id="content">

    </g>
  </g>
</svg>

View this example [SVG enabled browser only].

The g element is used for grouping design elements. Think of it as like groups in Photoshop. defs contains definitions for gradients, clipping paths, masks, filters and so on. The rect paints a simple rectangular at the top left, text draws text. Elements that come later in the document will be painted on top of their ancestors. There is no such thing as z-index. You can set many properties of SVG elements with CSS declarations, if you like.

  1. SVG uses an optional extended CSS syntax for styling.

To explain this advantage a little further, you can also embed external stylesheets (not yet supported in Inkscape) or use style elements like in HTML for document-wide declarations. If the designer and the developer share some preliminary considerations and agree on a base design, they can both use an embedded default stylesheet that already contains many style properties of the final HTML version, like font definitions.

SVG allows both attributes id and class on any element. They have the same meaning as in HTML and the same effect on CSS declarations, that is, you can address SVG elements with the #id/.classname notation.

Perhaps youʼve noticed, that although I used pixel units in the svg root element, the measures of the rectangular are unitless. This is a recommended practice to make SVG images scale more easily. The content of the SVG root element is then fitted into the viewport spanned by its size. Although this is a great feature of SVG, it has to be handled with care when trying to accomplish pixel-perfect designs.

Creating a Prototype

Now comes the fun part. SVG not only allows CSS but also JavaScript. And, even better, it has an a element to mark up links. This is exciting. Have you ever dreamed of an JPEG you can interact with? No? Iʼll show you, what you missed. First a bit code (shortened by the positioning attributes to increase readability):

<a xlink:href="http://www.manuel-strehl.de">
  <rect fill="yellow" />
  <text style="
      font: bold 1em Helvetica,Arial,sans-serif;
      fill: blue;">
    A link
  </text>
</a>

View this example [SVG enabled browser only].

The needed XLink namespace xmlns:xlink="http://www.w3.org/1999/xlink" is usually declared on the root element. Then you have a link element enveloping two design elements. The link works as expected with the target given in the xlink:href attribute. If you click on either the rect or the text the browser opens the link target just like any HTML link.

  1. SVG links allow single wireframes to be connected via hyperlinks.

Unfortunately Inkscape has no simple user interface to create links. But it is equipped with a very nice XML editor that you can use to create any element (even non-SVG ones). In this editor you can create a new link element and just drag and drop the elements, that should be clickable, inside it.

Screenshot of the XML editor in Inkscape with open “create new element” dialog.

With SVG links you can create a series of wireframes, that an evaluation user can follow directly in the browser. This is our first step to transform our wireframe into a working prototype.

In this context a prototype is meant to be a viewable web content a user can interact with. Neither is it meant to become part of the finished work nor has it to be based on HTML (think of Flash prototypes). All it should do is demonstrate how a finished page would work and react.

With this interpretion of a prototype in mind we can start adding behaviour to the SVG file. As we all have learned in Usability 101 styling is done with CSS and behaviour, strictly separated, with JavaScript. And exactly so we want to keep it with SVG, that is, with one small exception.

As an example, we will try to add a smooth hover effect to what will become a navigation bar. The JavaScript for this task is stored in an external file and embedded via SVGʼs script element, that works quite like the one in HTML. (Note that you have to use xlink:href instead of src.) We begin with the SVG source:

<?xml-stylesheet href="navigation.css" type="text/css"?>
<svg version="1.1"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    width="1000px" height="1000px">
  <title>Navigation</title>
  <defs>
    <script type="text/javascript"
               xlink:href="navigation.js" />
  </defs>
  <g id="page">

    <g id="navigation" class="normal">
      <rect x="0" y="10"
               width="100" height="80" />
      <rect x="110" y="10"
               width="100" height="80" />
      <rect x="220" y="10"
               width="100" height="80" />
    </g>

  </g>
</svg>

View this example [SVG enabled browser only].

At the very first line you see an XML processing instruction. This is a standardized way to embed external CSS or XSLT stylesheets into an XML file. SVG re-uses this syntax. Letʼs take a look at navigation.css.

@namespace url(http://www.w3.org/2000/svg);

#navigation rect {
  fill: blue;
}
#navigation rect:hover {
  fill: red;
}

The :hover, this is the small exception mentioned above, will just like that add nice effects to the SVG file, like we know them from HTML. With this technique you could also change, e.g., gradients for an object as easy as fill: url(svgfile.svg#my_gradient); and so simulate what will later become a classical CSS sprite. However, this cross-document referencing of style properties is not yet implemented in most browsers (but Firefox 3.5 and Opera 9.6). It will thus only work for embedded stylesheets and declarations of the form fill: url(#my_gradient);.

The :hover pseudo-property, together with the a element, gives us already the power to quite efficiently simulate an actual HTML page (if you leave forms aside). But if there are interactions that require some kind of animation, we still have the JavaScript file referenced within the script element, and animations are, what we do now.

SVG has support for SMIL animations, but since the browser support is not really good there, and Inkscape has no interface whatsoever for this, we use this as a learning example for JavaScript.

/* on window loading */
window.addEventListener("load", function() {
  var rects = document
               .getElementById("navigation")
               .getElementsByTagNameNS("http://www.w3.org/2000/svg", "rect");

  /* loop through all rects in the navigation */
  for (var i = 0; i < rects.length; i++) {
    /* do the hovering */
    rects[i].addEventListener("mouseover",
      function (event) {
        blue2red(event.target, 0);
      }, false);
    rects[i].addEventListener("mouseout",
      function (event) {
        red2blue(event.target, 0);
      }, false);
  }
}, false);

/* change the color from blue to red */
function blue2red(element, red) {
  red = Number(red) || 0;
  red += 5;
  element.style.setProperty("fill", "rgb("+
                            String(red)+", 0, "+String(255-red)+")", null);
  if (red < 255) {
    window.setTimeout(function () {
      blue2red(element, red);
    }, 10);
  }
};

function red2blue(element, blue) {
  /* likewise */
};

View difference to example 3 [SVG enabled browser only].

Now instead of the boring instant switch to red we have a nicely animated fading into the hover color. The script is intentionally kept simple and straight-forward, just two things should be mentioned:

  • We can safely use addEventListener() since the files will not be viewable in IE anyways.
  • Instead of directly setting element.style.fill we take the detour over element.style.setProperty(). This is due to limitations in browser support for the former.

So we keep as result:

  1. Behaviour can be added to SVG drafts with CSSʼs :hover and JavaScript.

From SVG to HTML

The goal of all this work is to create a fully functional HTML page that is viewable also in Internet Explorer. I have already mentioned, that a savvy planning of CSS can save you typing work, if you consistantly use IDs and classes in SVG and HTML. You can also achieve quite a lot of savings, if you take care in your JavaScript files, that DOM selection and manipulation are separated. For those of you using CSS selector engines like Sizzle (in jQuery or Dojo), $("#page") yields an element in both SVG and HTML.

Next we will need rasterized versions of the vector art. You have several possibilities here. The simplest is, to use Inkscapeʼs export feature via its GUI. You can select a region to be rasterized, and Inkscape will save the result as a PNG file.

My favourite for repeating tasks is scripting Inkscape or Illustrator. Adobe uses JavaScript, so you can put together a small JS file that does the rastering. Inkscape has several possibilities. You can use its command line interface to write a Bash script, or create a Perl, Python or XSLT extension and install that.

Another possibility is using one of the lots of libraries out there handling SVG like rsvg (used in MediaWiki) or ImageMagick. They have usually a clear interface and are designed for this kind of tasks.

SVG as Part of the Final Site

I threatened you, that I will loose a few words about including SVG in the final HTML page as well. Iʼll make it snappy.

In Firefox, Opera, Safari, Chrome and descendants using SVG inside XHTML is as simple as copy-and-paste. You only have to serve the XHTML with the correct MIME type, that is, with application/xhtml+xml, and embed your SVG inside the HTML code. If you are concerned about validation, try out this official W3C doctype declaration:

<!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
    "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">

It gets more complicated, if you want to respect IE. Luckily it also knows a vector graphics format, VML. This is, ironically, one of the two parents of SVG. So the way to go is serving VML to Internet Explorer and SVG to all others.

Here comes JavaScript into play, once again. It serves as an abstraction layer between browsers. If you want to read more on this, I suggest you to take a look at the Raphaël JavaScript library, which is tailored for exactly this task.

Disadvantages of this Approach

Now Iʼve been long enough crazy about SVG as basis for web design. Itʼs about time to get back on our feet. Where lie the problems?

If you have used other vector graphics formats already, or if youʼre using Photoshopʼs vector masks or paths, you will know what Iʼm talking about here: Aliasing. The final web page is rendered on a pixel based display. Imagine, that in your vector graphics program you place a line, 1px wide, not on the pixel raster, but exactly in between. It will land on the final screen as a 2px wide, half-opaque something looking quite nasty. There is no global switch to remedy this behaviour. The only thing that helps is self discipline. Use a grid and force yourself to obey its constrictions.

In SVG it is as simple as adding rx="10" to a rect to create rounded corners around a box. This simplicity however yields a problem to the poor developer having to create all these rounded corners in IE or Opera. The designer can get very fast into the nice possibilities within Inkscape and forget about the implementation. But then again, this also applies to PSD based designs.

There are some minor points where the SVG spec is not completely clear about how the rendering will look like. One example is the use of font sizes without a unit. If you experience weird font sizes, try to give the text elements a definitive size, preferably in pixel.

And finally, what I call the “Lorem ipsum problem”, running text in SVG 1.1 is an issue. It would have been addressed in the not yet finished SVG 1.2 with a specific element, and this even is implemented in Inkscape. Unfortunatelly browsers donʼt yet understand it. To the rescue comes once again the “XML-ness” of SVG. You can change, on server or client side, the flowRoot elements into HTML elements, and that the browsers can display correctly. The next two listings show the product of Inkscape and how a converted snippet could look like.

<flowRoot
    style="font-size:12px;">
  <flowRegion>
    <!-- defines the region
            of the running text -->
    <rect width="200" height="200"
           x="0" y="100" />
  </flowRegion>
  <flowPara>Lorem ipsum dolor sit amet.</flowPara>
</flowRoot>

View this example [SVG enabled browser only]. It will show a black rectangular.

<foreignObject x="0" y="100"
    width="200" height="200">
  <!-- foreignObject allows for 
         embedding non-SVG content -->
  <div xmlns="http://www.w3.org/1999/xhtml">
    <p>Lorem ipsum dolor sit amet.</p>
  </div>
</foreignObject>

View this example [SVG enabled browser only].

As a small gimmick take a look at example 7. This file uses the above feature of embedding XHTML in SVG in a quite nice way and demonstrates the power of the combination of both languages. I found the original idea at Mark Finkleʼs blog.

Summary

In this article I used SVG to create a website design in a vector drawing program. This SVG file was then modified with straight-forward CSS and DOM manipulation to create an instant prototype out of the wireframe.

This approach was successfully used to develop a design for Planet SVG and implement it as a Drupal theme.

If you already use, say, Adobe Illustator to do your web design, you can quickly try the suggestions in this article by exporting one of your designs as SVG and experimenting with that. However, if you are on the raster graphics train, all I suggest is, give vectors a chance.