boogdesign posts

Longer posts on standards based web design, portable web development and Linux, intermingled with some stuff on my other nerd interests.

Rob Crowther, London, UK based Blogger, Web Developer, Web Designer and System Administrator - read my Curriculum Vitae

Buy my book!

Book CoverHello! HTML5 and CSS3 available now

Buy my other book!

Book CoverEarly access to HTML5 in Action available now
« Arbitrary Element Rotation in IE - the Matrix Filter :: CSS with PHP »

Rounded Corners for Image Elements in Firefox with SVG

02/09/09

06:21:22 pm Permalink Rounded Corners for Image Elements in Firefox with SVG

Categories: Front End Web Development, Standards, HTML and CSS

In my post on CSS3 a few months back I mentioned some issues I had getting -moz-border-radius to clip content that it contained. After my writing the post the question came up a couple of times on stackoverflow, first from Brandon Wang and later a similar one from dougoftheabaci. Here is a simple example of the problem, the CSS is uncomplicated:

.target {
    border-radius: 20px;
    -moz-border-radius: 20px;
    -webkit-border-radius: 20px;
}

With that class applied direct to an img element it looks great in Safari and Chrome:

Example page in Chrome

But it doesn't work so well in Firefox:

Example page in Firefox

Today I came across the Applying SVG effects to HTML content article on the MDC wiki, one of the things it discusses is using SVG as a clipping mask for HTML elements. It occurred to me that it ought to be relatively straightforward to use a clipping mask to create the rounded corner effect directly on an img element in Firefox.

So I started off with the example code from the article, removed the circle, made the rectangle full size and used the rx and ry attributes to round the corners:

<svg:svg height="0">
    <svg:clipPath id="c1" clipPathUnits="objectBoundingBox">
        <svg:rect x="0" y="0" rx="0.05" ry="0.05" width="1" height="1"/>
    </svg:clipPath>
</svg:svg>

Then use a CSS class to apply it to my image:

.target { clip-path: url(#c1); }

It didn't work at first, but then I realised I'd created my document with a .html extension rather than .xhtml - to allow mixing of SVG into XHTML the document must have content type application/xhtml+xml. Once I fixed this the effect was exactly as I'd hoped:

Example SVG page in Firefox

Here is the full code. Of course, embedding it all this way isn't going to work for any browser other than Firefox 3.5, and serving application/xhtml+xml is going to break Internet Explorer, so it's not really a practical solution in it's current state. It's more useful to break the content into separate files, then the SVG can be served as image/svg+xml while your HTML is text/html. This final example works across browsers and will round the corners of the image in Chrome, Safari and Firefox.


Tweet this!
PermalinkPermalink

Comments:

Comment from: Bill [Visitor] · http://fisherwebdev.com
17/09/09 @ 23:24
This is *really* great stuff, but I am a little bit confused about the very last part:

"It's more useful to break the content into separate files, then the SVG can be served as image/svg+xml while your HTML is text/html."

I followed the link, and I understand that server configuration is important, but still I don't quite understand how to create the SVG resource file, where that goes on the server, etc.

any hints?

thanks!
Comment from: robertc [Member] · http://www.boogdesign.com/
18/09/09 @ 18:46
Hi Bill

The problem I'm referring to is that, in order to have the SVG included in the HTML recognised you have to serve the whole page as application/xhtml+xml. This leads to problems in IE, because it will then prompt you to download rather than display the web page.

If you put the SVG in a separate file then that can be served with it's own content type but the HTML can be served as standard text/html to be backwards compatible with Internet Explorer.

If you look at the page linked to from the text 'final example' at the end of my post you will see there is an external CSS file, rounded-corners.css, which then links to resources.svg to pick up the clipping rectangle. I found my apache was already correctly configured for SVG and using the correct content type.

All the files are in the same folder, so you should be able to download them easily.

Rob
Comment from: JK [Visitor] · http://jon-kyle.com
10/03/10 @ 22:47
You just saved my life?this was driving me CRAZY.

Thank you thank you thank you
Comment from: Bert Casier [Visitor]
16/09/10 @ 10:02
This is nice!

Is there a way to specify pixel values for the radius, on landscape images the ellipse width is distorted...
Comment from: robertc [Member] · http://www.boogdesign.com/
16/09/10 @ 11:41
Hi Bert. You would have to mess around with co-ordinate systems to get pixel equivalent values, a quick hack might be to use unequal values for rx and ry. Note that in Firefox 4.0 the issue preventing the use of CSS border-radius is now resolved fixed.

Rob