Rounded Corners for Image Elements in Firefox with SVG

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.