Dave Woods - Freelance Web Design Warwickshire

Adding Rounded Corners to Images Using CSS

The easiest way to make rounded corners on images is obviously by using Photoshop or other graphical software but when dealing with lots of images, this could become extremely tedious. So, what if there was a way of creating rounded corners for all your images using CSS? Well, within this tutorial I’ll show how this can be done.

Example

Here’s an example of the kind of effect you can achieve. As you may notice, this works with any size image, small or large and will apply the rounded effect to all corners of an image, irrelevant of the dimensions.

The Image

As with my CSS Rounded Corners Revisited tutorial, this guide will use just a single circular image, however due to how the transparency in the image is created, you’ll probably need to download the image and view it in a graphics package or display it on a coloured background to see how it actually works.

Essentially though, the image is a transparent circle with the corners filled with white.

HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head><title>Rounded Corners for a Foreground Image Using CSS</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div id="container">
<div class="image">
<span class="tl"></span><span class="tr"></span>
<img src="cat1.jpg" alt="">
<span class="bl"></span><span class="br"></span>
</div>
</div>
</body>
</html>

The HTML is pretty straight forward. I’m using a container for the image itself and then within this I’m including a span for each of the corners.

CSS

To start the CSS, I’ll include some simple formating which resets padding and margin, forces scrollbars in Firefox/Opera, adds a little bit of padding for the body and also forces the images we’re dealing with to display as block as this squashes some IE bugs.

* {
padding: 0; margin: 0;
}
html {
overflow-y: scroll;
}
body {
padding: 10px;
}
.image img {
display: block;
}

Next, we’ll float the container of the image so that it collapses to the width of the image and we’ll also apply a position: relative. Whilst the relative positioning doesn’t do anything at this stage, we’ll be absolute positioning the corners within the image and therefore this will provide a surrounding area for the absolute positioning to work.

.image {
position: relative;
float: left;
}

With the foundations in place, we can now start to apply the positioning of the corners. You could apply all these styles to each corner but as they’ll be the same for all four corners, I’ve setup a style that applies the style to all of the span’s within the container. This applies the same width and height, same background image and tells each span that it’s going to be absolute positioned. I’ve also used font-size: 0; to kill the small height bug in IE6.

.image span {
width: 16px;
height: 16px;
font-size: 0;
background-image: url(rounded-corners.gif);
position: absolute;
}

Next, we need to provide the positioning for each of the images and also change the background position to show the corner of the image that needs to be displayed.

As you’ll see from the next bit of code, it’s quite simple to position each corner in place and then using the background-position to slide the correct part of the image into view.

.tl {
top: 0;
left: 0;
}
.tr {
top: 0;
right: 0;
background-position: 16px 0;
}
.bl {
bottom: 0;
left: 0;
background-position: 0 16px;
}
.br {
bottom: 0;
right: 0;
background-position: 16px 16px;
}

For IE7, Firefox, Opera and Safari, this will work absolutely fine without any problems but for IE6 there’s a slight problem where some of the corners are sitting just 1px out from where they should.

I’ve not encountered this problem before but have managed to correct this by providing absolute positioning just to IE6 which seems to fix the problem.

* html .tr {
right: -1px;
}
* html .bl {
bottom: -1px;
}
* html .br {
bottom: -1px;
right: -1px;
}

It’s only the bottom and right edges that seem to have the problem and there may be a better or easier fix than this one but it does seem to do the trick.

Since putting this tutorial together, I’ve spoken to Paul O’Brien and there doesn’t seem to be a simple fix for the problem (his explanation for this problem is available here: IE 1px discrepancy).

Summary

And that’s all there is to it. You can use any image of any size within your HTML and using this method, the images will always appear with rounded corners.

You may want to use a PNG image with transparency for smoother rounding and then use a PNG fix for IE6. I’ve opted not to for this tutorial just to keep things simple and will attempt to explain how the PNG fix works another time.

12 comments on “Adding Rounded Corners to Images Using CSS

  1. Jermayn Parker

    I wont comment on the cat images 😐

    I like it! Do you think there is a way to make the corner image to inherit the same colour as the background?

    I ask because while its cool if the background is white, it looks a bit weird if the background get changes to another colour. I realise that you only need to change one image BUT it would be nice to see it work!!

  2. Dave Post author

    What’s wrong with the cat images? :o)

    I don’t think that would be possible with CSS alone unfortunately. You’d kind of need some clever logic in the image to say that you want one bit transparent and to show a solid colour but you want the other transparent bit to show the image which just isn’t possible.

    There may be a way with JavaScript but for the sake of just creating one extra image for each background colour you’re using, I’d probably tend to go down that route instead of using JavaScript which may not be available to everyone.

  3. Andrew

    That first tiny kitten I’ve seen too many times in “Save teh kittens from lipstick labs!!1” banners…

    Nice CSS trick, but I’m still hoping for a way to do this without presentational CSS. My first reaction would be to add the necessary HTML to class’d images using nonintrusive JS. But, like you said, that leaves everyone without JS out in the cold.

    The only real solution that comes to my mind in answer to Jermayn’s question would be to use a PHP page to fetch the image, make certain areas transparent, and output the result as either PNG of GIF. Of course, this would preclude the need for CSS tricks. And it would require recoding all your img tags to call the new “image page”, so it might not be all that practical.

    Good article at any rate 🙂

    Andrew

  4. Dave Post author

    Hi Andrew, Thanks for your comment.

    Here’s hoping that CSS3 comes along quickly as I suspect that using multiple background images you’d be able to apply all four images to a container and then position them accordingly. It’s likely to be a few years before that’s widely supported though and even longer before we don’t need to support the current browser which obviously don’t support this method yet.

  5. Matt

    Thanks Dave, this is fantastic! I have been looking for something like this for a while. In automatically generating thumbnails for a website, this makes things that much snazzier. 🙂

  6. kipp

    Greetings,

    If you combine the transparent gif idea with some CSS-transparency settings, you can get a much smoother edge on those rounded corners. Check out the cross-fading oval image on this page: http://violavalleywildflowers.com/

    It uses a few concentric transparent gifs and CSS-transparency to create the rounded frame for eht erectangular images behind it.

    For your purposes, it would require 4 rounded corner images (each slightly smaller than the last) – but the edge would be less jaggy.

  7. Bruce

    Very difficult (impossible) to achieve rounded corners in CSS 2.1 alone without sacrificing semantic mark-up, which some hold in higher regard than others. Not meaning to criticize your technique in particular Dave; it’s a common problem. I recently reviewed various methods of corner-creation (CSS, JavaScript, SVG, Flash, images, jQuery) and all this effort merely convinced me that CSS3 is the answer we needed yesterday. Ultimately I chose to use draft CSS3 for WebKit browsers but inject it via the DOM using jQuery, thus retaining a valid stylesheet. It’s a cheat to be sure, but to my mind better than littering my pages with redundant mark-up I’ll likely resent later. At least I can remove my cheat without effort once (if) CSS3 becomes a W3C standard. My 2 cents 😉

  8. Dave Post author

    Hi Bruce, JavaScript is definitely an alternative and I’ve nothing against people using that method. Personally, I like to deliver the same experience to all users so don’t mind using the extra bit of markup but I fully understand why some people don’t so think it’s always down to personal preference.

  9. Pingback: Recursos y Tutoriales » Blog Archive » 500 links de recursos para diseñadores y desarrolladores web

  10. Kelly

    I wanted to let you know that your code doesn’t work with using a fixed transparent png in ie7 or ie6. I may be forgetting something, but I don’t think so. Here is my code. Let me know if there is something that I forgot.

    Thanks,
    Kelly

    .image span {
    width: 16px;
    height: 16px;
    font-size: 0;
    background-image: url(rounded-corners.png);
    * background: transparent; z-index: 0;
    * filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’rounded-corners.png’, sizingMethod=’fixed’);
    position: absolute;
    overflow:hidden;
    }

  11. Müfit Kiper

    Hi Dave!

    Thank you for this great tutorial. It came in really handy.
    @Kelly, I tried it with png-files as well and I suspect that the problem is with IE:s filter. If you use the alpha filter IE6 seems to ignore the CSS for that element.
    You probably need to use the IE filters for the positioning as well…