Categories
Opera blog post Web development

SVG Multiple Images and Rounded Corners

One of the geekier things that excite me (okay, I guess there’s a lot of those) are upcoming features in web browsers. Specifically when it comes to new and improved support for things like CSS3, Javascript and SVG.

UPDATE March 17, 2009:

For an easy way to generate rounded corner SVG files, see my border-radius for all! post.


One of the geekier things that excite me (okay, I guess there’s a lot of those) are upcoming features in web browsers. Specifically when it comes to new and improved support for things like CSS3, Javascript and SVG.

The recently released Opera 9.5 alpha is known for it’s improved CSS support, but what excited me most was the ability to use an SVG file as a background image. Why is this great? It allows for all sorts of neat things. Small file scaling gradients, multiple raster images, even animation!

Sure, no other browser supports this yet, but I’m not going to let that ruin my fun in designing for the future. Besides, one could always use javascript to fix stuff for other browsers if really necessary.

So, even before Kestel was released I tried my hand at a multiple image SVG background. CSS3 allows multiple images to be specified as background, but so far only Safari supports that. I’d noticed an example of this a while back, and since this seemed very useful to me, I based my example on it as accurately as I could.

The first 9.5 alpha ALMOST displays it correctly…unfortunately it displays a black box for the top and bottom “border”. This strikes me as odd since it works fine as standalone file, but I’m sure it will be fixed eventually.

Since I made this, Opera’s Chief Web Opener David Storey made some excellent demos showing other new options, including SVG rounded corners. Rounded corners, too, are a CSS3 property, which work in Firefox (for example). Opera currently lacks support for this web 2.0-riffic display trick, so it’s cool to now have a way to emulate them without a need for Javascript or nested DIVs.

David’s example shows an easy to make single color background with rounded corners. However, what if you only wanted to have the border? The obvious answer would be to add a “stroke” to the SVG rectangle. Unfortunately, the stroke sits right on top of the edge of the rectangle, and so parts will be clipped off when putting it in a box. You might be able to get away with a 1-pixel border, but beyond that is just not acceptable.

Lacking the ability to display the stroke on the inside of the box, one would have to give the inner box a certain margin from the outer box. Ideally using an absolute value like 5px, rather than a percentage. For my multiple background image I kind of dealt with this when needing to position the right and bottom border. With HTML one would use CSS to do “position:fixed” and “right:5px”. Alas, this won’t work in SVG, where you can only specify a top and left position.

So, what I did was give it an “x” value of 100%, and then use the transform=”translate()” attribute to move it back to the left using a pixel value. Ta da, an image stuck to the right border. This, however, was using multiple images, not one great big rectangle.

Eventually, however, I found the solution using USE elements, clipping areas, and four different rectangles. Crazy? Yes. But it works quite well, allowing different radii for each corner, any given margin, any color and any stroke width.

Here is the result, which I’m quite proud of:
The standalone SVG file

I hope to add more examples later, including using the image as background, and some documentation on modifying the file.

I wouldn’t be at all surprised if someone comes up with a more efficient way of doing this, if you do, please let me know!

4 replies on “SVG Multiple Images and Rounded Corners”

Having such universal solution would be great even if it would required additional markup or JavaScript. So, Opera will get scalable SVG background, but others will get raster image.

Thanks! And good question. There are a different options for different browsers…I’ll see if I can come up with a detailed solution in a future blog post.