A New Can of Worms - SVG as Website Graphics

As I mentioned earlier the upcoming release of Opera 9.5 comes with 2 long awaited features: SVG as background-image (CSS), and SVG via <img/>. The alpha versions were buggy all over the place, but the freshly released beta seems to be pretty stable.

So, what is it good for? Good question. I also wondered about that. This is what I came up with:

svg_demo.html (screenshot)

Be sure to check out the the resize and zooming behavior. It's pretty nifty.

Unfortunately there were a few things which didn't work, because the spec doesn't allow it. Path data for example cannot contain units. With units you could for example jump to the lower right corner (100% 100%) and draw relatively from there. That would allow a lot more resizing control. Also a negative width or height for rect doesn't work. It's not valid according to the specs.

So, what does work? A handful of useful things fortunately. Let's take a closer look! :)

The layout

the layout

SVGs with width/height set to 100%

H1: headerbg.svgz
H2: smenu.svgz
H3: iblock.svgz
H4: prototab.svgz (hover: prototab2.svgz)

SVGs with viewBox attribute

V1: logo.svgz
V2: pillbutton.svgz (hover: pillbutton2.svgz)
V3a/V3b: rotate_animation.svgz
V4: k.svgz

All SVGs were created with Inkscape, manually edited, and cleaned up if I felt like doing so. With the "Save for Web" extension (which I haven't finished yet) it should be less of a hassle.

For the adventurous people I'll try to explain it briefly.

Setting width and height to 100% (round corners)

  • Set the document's width and height to something sensible (e.g. 64px * 64px).
  • Setup the grid (eg set the x and y spacing to 16px).
  • Enable the grid (#).
  • Draw a Rectangle in the size of the document.
  • Make it round (e.g. set rx and ry to 16px).
  • Save as plain SVG.

Not that difficult so far, right? Then open it in a text editor and...

  • Replace the width and height attributes in the svg-element with "100%".
  • Replace the width and height attributes in the rect-element with "100%".
  • Clean up the style stuff etc if you like.

The result:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.0" width="100%" height="100%">
  <rect width="100%" height="100%" rx="16" ry="16" x="0" y="0" style="fill:#eee"/>
</svg>

If we now use that SVG as background, it will always fill the complete size of the element and the radius of the corners will always stay the same. There won't be any need for extra markup anymore. Awesome, huh?

For the tabs in the upper right corner I used a rounded rectangle with a non-rounded one (which is 50% in height) on top. Both share the same gradient, which ensures a seamless look. Feel free to check out the source.

Using the viewBox attribute

This is actually pretty easy once you've got the hang of it. For the most part you'll want to use a "meet" flavor of the preserveAspectRatio attribute. Which means the view box touches the viewport from the inside while keeping its aspect ratio.

The default value for preserveAspectRatio is "xMidYMid meet". Which basically means that the view box is placed in the middle of the viewport and then it grows until it hits a wall. I used this default value for all viewBox-SVGs. The excpetion is k.svgz which uses "xMaxYMax meet" (=slide into the lower right corner).

If you're fine with the default value of preserveAspectRatio, you'll only need to replace (not add, replace!) the width and height attributes in the svg element with a matching viewBox attribute.

For example:

<svg [...] width="640" height="480">

Becomes:

<svg [...] viewBox="0 0 640 480">

If it should slide around add preserveAspectRatio with a the proper value ("meet" actually isn't required, because it's the default):

<svg [...] viewBox="0 0 640 480" preserveAspectRatio="xMaxYMax meet">

For more details on this topic take a look at the specs.

Notes on animation

In Opera 9.5 SMIL animations don't work for background images. They do work fine for <img/> tho. That's the reason why the upper one (V3a) rotates and the lower one (V3b) doesn't. Also note that JavaScript animations won't work with background images or <img/>, because that would be a big security issue.

Of course JavaScript animation will continue to work with embed/object if it's viewed directly or if it's part of this document's DOM.

Demo download

SVG: svg_layout_demo.zip (13kb)
SVGZ: svg_layout_demo_compressed.zip (13kb)

Comments

Firefox

I hope that Firefox will support this feature soon, too, since it seems to be pretty nice and neat. Anyway: as long as IE 7 (8) won't support it, you can't really use it, which is kind of sad. But it's really nice. :)

--Christian

FF

The Mozilla guys will eventually add that stuff somewhere after the 3.0 release (most likely with 3.5 - according to one developer). It has been in the bug tracker for ages.

Hovering

I guess it would be better if the images with hovering state would be i.e split horizontally with different states up and down. Though I'm not sure if it will work perfectly with CSS's background position of 50% and it might need to have the height then, so maybe it wouldn't be perfect...

I like what you made and am sure that this is how the future is going to be...

Re: Hover

Ye, I know how the usual rollover without preload stuff works. However, those techniques don't work in this case, because the dimensions are completely undefined. With fixed dimensions it would work again, but that would destroy most of the scaling.

I also experimented with hover styles for the SVGs directly, but that didn't work well, because the text was layered on top. However, I already have lots of other ideas, which I'll cover in a follow up article.

Firefox and web with SVG

Hello, firefox supports SVG pages as you can see in my page: http://filyp.gjgt.sk/index.xml
Created in Inkscape and edited in PSPad.

Ye

I know that FF supports SVG, but it doesn't support SVG via img tags or CSS yet. And while mixing namespaces is somewhat interesting (did a few demos myself), it isn't what most people want. Usually one wants to separate content and layout as much as possible. With mixed namespaces it's very interweaved to begin with and it's even slightly worse than that - images are also part of the document.

That's why mixing namespaces isn't that interesting for most people. Using SVG via CSS or image tags, however, is pretty versatile and it also adheres to the usual (sensible) paradigm. Additionally, it doesn't change the workflow at all. E.g. if you want a different button graphic just replace that button graphic and be done with it.

On a side note: My demo is more or less broken with all Opera 9.5 betas which were released after the article was written. By the looks of it they introduced some viewport size glitch. I hope they'll fix that in time. Otherwise this new feature will be pretty useless.

Post new comment

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options