Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

Rounded Corner Rendering in newer Browsers


:P
On this page:

It’s pretty sad that we’re even having this discussion about rounded corners in HTML in this day and age of prolific Web UI interfaces. But creating rounded corners that work in all browsers is a royal pain in the ass. It’s strange that rounded corners have created such an amount of attention, but I think there’s no denying that they do make for a nicer and more pleasant user experience – they give a user interface a more polished look and feel even if there’s no real tangible benefit. Ouch that sharp corner really poked me in the eye! ;-}

There are lots of solutions out there for this particular problem. In fact you can search around the Web until you’re blue in the face and still not hit all the clever hacks people have come up with to deal with this issue. Short of using custom images (which is what most big name sites with art departments seem to do for maximum compatibility) if you truly want to support browsers old and new creating rounded corners becomes a messy proposition. There are solutions that use JavaScript (here and here) to dynamically create rounded corners and there are solutions that use images (here and here) and onion layers to create the corners.

The good news is that CSS 3.0 actually supports rounded corners natively. The bad news is that CSS 3.0 has been and likely is going to be off for a while to come yet. However many of the latest batch of browsers including FireFox 3.5, Safari 4.0 and Chrome actually already support some of the CSS 3 feature set including rounded corners and shadows. Internet Explorer – not so much, but no surprise there. Opera also doesn’t support it yet.

Anyway, the point is that you can start taking advantage of the native support of rounded corners in browsers today if you don’t mind providing an experience that varies between browsers. I realize for some applications this may not be an option, but remember that if you do chose to render these browser specific extensions you’re not breaking layout you’re just ‘gracefully degrading to legacy behavior’. That sounds so Microsoft except it’s working against MS and IE this time around.

For example, here is a page in a small app I’m working on at the moment. The following is rendered in FireFox 3.5 with –moz-border-radius on the fieldset (outer box) and the individual items in the list:

Rounded

and here is that same page rendered in Internet Explorer 8 where rounded corner rendering doesn’t work:

NotRounded

To my eye at least the first looks much nicer and while the second one does look different it’s not so vastly different as to interfere with the overall design.

All this uses is the border-radius CSS tag or rather the –moz and –webkit versions thereof that currently support this functionality in their respective browsers.

The big advantage over the CSS based tags is that they are easy to administer and fully self contained. There are no images or other layout dependencies to deal with, you just apply the appropriate border radius and off you go. Further the CSS applied borders also respect border colors and so you can even do basic border shadow simulations as can be seen in the outline of the first image. They also deal more gracefully with contained content than some of the JavaScript or image solutions which don’t handle transparency and background images in many cases. The native behavior just works as you would expect in most cases.

So what does the CSS look like? It’s simple enough as shown in the two elements that use the borders (the frame and each detail item):

.snippet,.snippetofauthor
{
    padding: 10px;    
    background-image: url(images/LightBlueGradient.png);
    background-repeat: repeat-x;
    background-position: 0px -10px;
    border: solid 1px silver;
    margin: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
border-radius: 5px;
} .snippetofauthor { background-image: url(images/LightOrangeGradient.png); }
#divContainerContent
{
  margin: 0px 20px 10px 25px;
  margin-left: 25px; 
  margin-bottom: 10px;
  background: white;   
  min-width: 400px;       
  width: 70%;
  float:left;
  border-top: solid 1px silver;
  border-left: solid 1px silver;
  border-right: solid 2px #535353 ;
  border-bottom: solid 2px #535353;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  border-radius: 10px;
}

Current implementations of browsers implement CSS 3 custom browser extensions so they use the browser specific prefix (-moz, –webkit – remember that Chrome is based on WebKit as well). You can find out more about these tags on the Mozilla browser site: –moz-border-radius. You can specify the radius for each of the corners border-radius-topleft/topright/bottomright/bottomleft tags or by specifying multiple values (like margins) on the border-radius tag itself.

I added the plain border-radius tag in anticipation of true CSS 3.0 support in the future. Right now this is ignored but as CSS 3 becomes available more browsers can take advantage of the rounded corners as well.

While you’re over at the Mozilla site you can also poke around the various –moz extensions, many of which are part of CSS 3 as well. There are quite a few cool features coming and already working in FireFox. For example, the –moz-box-shadow functionality allows for easy drop shadows that makes a dialog like the following possible using only CSS without explicit images (except the content specific images):

CssDialog

Here’s the whole thing including draggable and closable (using the West Wind West Wind Web Toolkit’s jQuery plugins):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <style type="text/css">
    body 
    {
        font-family: Verdana, Arial, Sans-Serif;
        font-size: 10pt;
    }
    h2
    {
        color: maroon;
        font-size: 14pt;
        font-weight: bold;
        margin-bottom: 0pt;
        margin-top: 0pt;
        padding-bottom: 0pt;
        padding-top: 0pt;
    }
    .containercontent
    {
        padding: 15px;
    }
    .dialog
    {                
        background-image: url(css/images/LightBlueGradient.png);
        background-repeat: repeat-x;
        background-position: 0px -10px;
        border: solid 1px silver;
        margin: 5px;
        -moz-border-radius: 10px 10px 5px 5px;
        -webkit-border-radius: 5px;
        border-radius: 5px;
        -moz-box-shadow: #535353 3px 3px 4px;
-webkit-box-shadow: #535353 3px 3px 4px;
} .closebox { position: absolute; right: 5px; top: 5px; background-image: url(css/images/close.gif); background-repeat: no-repeat; width: 14px; height: 14px; cursor: pointer; } .closebox:hover { background-color: white; } </style> <script src="Scripts/jquery.min.js" type="text/javascript"></script> <script src="Scripts/ww.jquery.js" type="text/javascript"></script> </head> <body> <div class="dialog" id="divDialog" style="position: absolute; width: 500px;"> <div style="padding: 8px;" id="divDialogHeader"><h2>Dialog Header</h2></div> <div class="containercontent"> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has
been the industry's standard dummy text ever since the 1500s, when an unknown printer took
     </div>
    <div class="containercontent">
        <input type="button" disabled="disabled" value="press me" />
    </div>
    <div>
    
    <script type="text/javascript">
        $(document).ready(function() {
            $("#divDialog")
                .draggable({ handle: $("#divDialogHeader") })
                .closable();
        });                    
    </script>
</body>
</html>

Who needs a dialog plug-in when the layout is that simple? No images or support for corners or shadows. This is the way it should be. Unfortunately it’ll be a while until this functionality is coming in browsers, but at least it’s on the drawing board. Running the same thing in IE results in a less pleasant but still usable experience:
IEDialog[4]

The rounded corner functionality works well where supported in browsers, but there’s one gotcha I noticed: If you have container content that is square inside of a rounded box the inside element bleeds out of the rounded box. Check out the following undesirable display:

<div class="dialog" id="divDialog" style="position: absolute;  width: 500px;">    
    <div style="padding: 8px;background: steelblue;" id="divDialogHeader"><h2>Dialog Header</h2></div>
    <div class="containercontent">
        Lorem Ipsum is simply dummy text of the printing and typesetting industry. 
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
    </div>
    <div class="containercontent">
        <input type="button" disabled="disabled" value="press me" />
    </div>
<div>

When specifying a background image for contained elements that normally overlap the corners these elements render squarely. Square Hole Round Peg anyone:

 RoundPegSquareHole

Notice how the square <div> in blue tag overlays the round corners. I guess I would expect this to render the inner div inside of the rounded box, but both Mozilla and WebKit agree on this so I suspect this is by design. The bottom line is that for dialog displays like this you probably have to use a background image (as in the previous image example) or stick to a single color rather than nested div tags that provide the header backgrounds.

Normally I’m against using browser specific features but because this particular functionality provides an often requested feature now with minimal effort in an easily forward compatible manner, I’ve taken to using it selectively in some of my internal projects. If nothing else it gives an opportunity to start using these features in your designs now.

Posted in CSS  HTML  

The Voices of Reason


 

JLipford
July 08, 2009

# re: Rounded Corner Rendering in newer Browsers

Rick,

I have found a nifty jquery canvas solution. I natively am working with IE7+ but for the IE specific guys this background canvus plugin works quite nicely.

http://www.maierhofer.de/BackgroundCanvas.htm

Kevin Dente
July 08, 2009

# re: Rounded Corner Rendering in newer Browsers

I'm generally in the "use JQuery to fill the IE holes" camp now. So I use native rounded corners for "real" browsers, and a jQuery plugin for IE. Haven't found a totally perfect solution for drop-shadows yet though.

Rick Strahl
July 08, 2009

# re: Rounded Corner Rendering in newer Browsers

@Kevin - the problem with the various plug-ins is that they don't do well with non-white backgrounds and content inside of the cornered element.

However, the biggest deterrent is that it requires even a little bit of code which runs into the separation of concerns area. I like my UI to stay UI without requiring code.

Kevin Dente
July 08, 2009

# re: Rounded Corner Rendering in newer Browsers

Have you tried this one?
http://malsup.com/jquery/corner/

Judging from the demo page, it doesn't look like non-white background is a problem (didn't explore that on my own project though).

As for a the SOC issue - well, ideally I would agree, but IE isn't an ideal world is it? :) If a little jQuery magic can spruce up the site on IE (which, let's face it, still has the largest market share), I'm willing to go there. It probably won't be the only hack I do for IE after all.

Kevin Dente
July 08, 2009

# re: Rounded Corner Rendering in newer Browsers

Oops, forgot to mention that I don't know about the "content in the rounded corner" issue with that particular plugin - haven't tried it.

I've also used this image approach for rounded corners across browsers:
http://www.schillmania.com/projects/dialog2/

It was a pain.

Doug Dodge
July 08, 2009

# re: Rounded Corner Rendering in newer Browsers

Rick,

I remember reading many years ago about how Walt & Roy Disney, when they designed the original Disneyland, that they very deliberately made sure there were absolutely as few square corners as possible. The reason was that they had determined that rounded corners, as opposed to square (sharp) corners, were less 'hostile', and they wanted their guests to feel more comfortable.

Apparently there is quite a bit of psychological impact going on, although I suspect very few people actually think about stuff like that. *G*

I suspect that folks are attracted to rounded corners but don't really think about it at a conscious level.

"Ouch that sharp corner really poked me in the eye!"

*s*

Best,

DD

Anthony Bouch
July 14, 2009

# re: Rounded Corner Rendering in newer Browsers

Nice post. I've always leaned more towards the UI side of dev - and have thrown myself at rounded corners a few times on a couple of projects. I agree with @DD above - that it does make a difference in terms of user experience and how people 'feel' about a site, or application.

I think it's a shame that MS haven't moved along with the others in this area. The browser wars are definitely 'reloaded' so it will be interesting to see how things develop.

Paul Chasan
January 09, 2010

# Simple Fix for Background Image Poking Through Rounded Corners

Hi thanks for posting this,

I've just spent hours trying to resolve the issues you mention at the end of your post where a background image in a nested DIV tag, poke through a rounded border in the parent tag. Your blog post convinced me that no amount of tweaking my CSS would fix the problem.

I just figured out a simple workaround that seems to be working on Safari and Firefox on the Mac (but be forewarned, I haven't tested it in IE or on a Window's machine).

It involves masking out the offending corners in Photoshop and then saving out the background image as a PNG with a transparent background. The beauty of it is that you don't have to deal with patching the corners using CSS to absolutley images usi

Here's the trick: rather than deal with absolutely positioned corner images, simply open the background image in Photoshop.

Using the Rounded Rectangle tool, draw a rectangle that lines up EXACTLY with the edges of the offending image corners. Make sure to set the rectangle corner radius to the same dimension as the corners you set u in your CSS code. (In my case it was 10px.)

Then make a selection of the new just created rounded rectangle by command-clicking the layer (control click on a PC). [Note: in my case I only needed to hide the top corners. To prevent masking out the bottom corners, I added them to the selection by holding down shift with the Rectangular Marquee tool and dragging the cursor over the bottom corners of the image.] Everything should now be selected except the bits of the corners that you want to hide.

Next, hide the new rounded rectangle layer by poking it in the eye.

Select the layer with the offending corners and at the bottom of the layer's pallet, click the "Add Vector Mask" button.

Now make sure that you don't have a background layer turned on and save the image as a PNG with transparency turned on. If you are using the PNG-8 format, bake sure you select Matte = none

Then, Viola! no poking corners

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024