bioneural.net site preferences

Accessibility

Toggle width/ text size:

style

Default/Alternate

Suits visual impairment, mobile devices

Styling

Change the theme:

layout

NB: may reduce functionality

Link behaviour

Links with an icon are off-site:

links

Right-click any link to optionally open in a new window or tab


Internet

The best way to do corners and gradients

Rounded corners. Yes, they may be a "Web 2.0" fashion fad, but it has been clearly documented that they're a lot easier to make than square ones. As part of my overhaul of bioneural.net I've been optimizing much of the code "under the hood", meaning a lot of the changes aren't even visible. Re-evaluating how things are put together, and considering how they could be done more efficiently or otherwise improved is a valuable exercise—that it scratches a perfectionist itch is an added bonus. In this article I look at a variety of methods for creating boxes with rounded corners and gradients. Yep, it's a showdown!

The traditional approach

The well-established method of adding corners or gradients to an element is to use multiple background images. Depending to some extent on your content, this is typically impossible to achieve without the use of non-semantic extra mark-up. For example, this box uses to extra and empty divs:

<div class="curvetop"></div>
<div class="curvemid">
	<h2>Willkommen! Welcome!</h2>
	<p class="german" xml:lang="de" lang="de">Willkommen auf der Projekt Koru Seite, wo Simone &amp; Bruce die praktischen Aspekte eines Jahres in Neuseeland mit Euch teilen wollen. Eine Einf&uuml;hrung findet Ihr <a href="http://www.bioneural.net/2006/03/17/introducing-project-koru/">hier</a> zusammen mit einer <a href="http://www.bioneural.net/2006/03/30/the-teachings-of-te-koru/">Erkl&auml;rung</a> warum wir das Koru als Symbol unserer Reise gew&auml;hlt haben.</p>
	<p class="english">Welcome to Project Koru, where Simone &amp; Bruce share insight into the practicalities of organizing a year in New Zealand. You can find an introduction to the project <a href="http://www.bioneural.net/2006/03/17/introducing-project-koru/">here</a> together with an <a href="http://www.bioneural.net/2006/03/30/the-teachings-of-te-koru/">explanation</a> of why we chose the koru as the symbol for our journey.</p>
</div>
<div class="curvebottom"></div>

Three gradient images (2 having one rounded corner each) could then be loaded into the background of each of the three "layout classes" via CSS:

.curvetop { height: 15px; background: #fff url('gradient-top.png') bottom left no-repeat; display: block; position: relative; margin-top: 10px; }
.curvemid { background: #fff url('gradient-bg.png') repeat-y; padding: 2px 20px !important; display: block; }
.curvebottom { height: 15px; background: #fff url('gradient-bottom.png') top left no-repeat; display: block; position: relative; margin-bottom: 10px; }

The result:

rounded-welcome.jpg

You could use this exact same technique for adding embellishments like borders, drop shadows and the like—but not without some Photoshop skills and a decent collection of bandwidth-hogging images if you needed multiple box styles.

The challenge

I devised a box that I thought would test the mettle of any technique. It consisted of just one div containing a header and a paragraph, the text in each of which should appear over a different background with one of these being a gradient (but not necessarily an image). The box should be formed with rounded corners (including on images), a white border, and a drop shadow. It should also have a number of functional characteristics:

  • Minimal mark-up i.e. avoiding nested and/or empty tags;
  • No changes to mark-up required (but extra CSS allowed, since this could be moved to an external stlesheet);
  • Valid XHTML and CSS (2.1);
  • Anti-aliasing on the corners (inner and outer border edges);
  • Small footprint (let's say under 20KB);
  • If using JavaScript it should degrade gracefully (i.e. still looks OK if JavaScript is disabled);
  • Liquid container (adjusting container width to both content size and browser window dimensions).

Why the requirement for minimal markup? Forward planning. Eventually CSS3 will arrive, and there'll be no need to scour your database in order to clean out all that redundant mark-up. Just amend your CSS and delete any unemployed images or JavaScript.

My template XHTML and CSS rendered the following:

master.jpg

Finding a solution to fulfil most if not all of my form and function requirements was going to be something of a mission. There's a useful roundup of techniques here, divided into those based on CSS and those based on JavaScript, with examples in both groups requiring anything from no images at all through to eight images. A particular difficulty was finding techniques not restricted by the dimensions of any required image; many of the earlier established methods were clearly devised before the availability of 23" widescreen displays (example.)

I made a shortlist (in no particular order) of techniques that looked promising and set to work. I'm not going to post all the code directly into this article or it will become over-long. The files I used for each technique, together with the master template and original full packages where applicable, are available for download should you wish checkout the code or conduct further experiments. I've tested only in Safari and Firefox.

Download the test files here (.zip archive, 428KB).

Nifty Corners Cube

First up is Nifty Corners Cube by Alessandro Fulciniti. This method uses JavaScript and CSS; no images other than those you wish to use as backgrounds are required. Here is the result:

nifty.jpg

Scoresheet:

Photo background: Supported.

Gradient background: Supported.

Four rounded corners: Yes.

Border: While you can produce a convincing rounded border, using padding on the container, this would require extra mark-up in our example in order to retain the cornering on our background images.

Drop shadow: Not supported.

Minimal mark-up: An extra container is required to render a border with inside and outside rounding.

Static mark-up: Mark-up edited to add extra container plus insert box-specific script.

W3C validity: Yes.

Anti-aliasing: Anti-aliasing is not working on the background images or border, although it does work on solid colour boxes in the examples.

Small footprint: 10KB for CSS and JavaScript (background images additional).

Graceful degradation: Renders as per the master if JavaScript disabled.

Liquidity: Overriding fixed width for .cornered (and in the third case for .xtra) supports liquid layouts (case four).

Score: 8/12

curvyCorners

Cameron Cooke's curvyCorners is another image-free JavaScript solution:

curvy.jpg

Scoresheet:

Photo background: Supported.

Gradient background: Supported.

Four rounded corners: There are rounded corners, but these are rendered adjacent to our background content rather than on top of it. This example illustrates rounding on a background image, but adding a border to the containing div merely fills the cornered area with "extra" offset background (see here).

Border: Obtained by applying background and border to container.

Drop shadow: Not a feature of this technique.

Minimal mark-up: Yes.

Static mark-up: Mark-up edited to insert box-specific script.

W3C validity: Yes.

Anti-aliasing: Yes, but only on the outside of the rounded border (not on images).

Small footprint: 24KB for JavaScript (background images additional).

Graceful degradation: Renders as per the master if JavaScript disabled.

Liquidity: Overriding fixed width for .cornered supports liquid layouts (case four).

Score: 7/12

SRCCB

The "simple rounded corner CSS boxes" technique was devised by Ryan Thrash, also accessible in the form of an online generator as Spiffy Box. It uses no JavaScript and a single image combined with moderately complex CSS (which would have to be recalculated for each box size):

simple.jpg

Scoresheet:

Photo background: Supported (integrated into container background).

Gradient background: Supported (integrated into container background).

Four rounded corners: Yes (integrated into container background).

Border: Yes (integrated into container background).

Drop shadow: Yes (integrated into container background).

Minimal mark-up: Requires two additional divs for positioning purposes.

Static mark-up: Mark-up edited to insert two additional divs.

W3C validity: Yes.

Anti-aliasing: Yes (integrated into container background).

Small footprint: 6KB image overhead compared to master with original 2 background images.

Graceful degradation: Not applicable as no JavaScript.

Liquidity: Depends upon fixed-width images.

Score: 9/12

swfIR

The SWF Image Replacement (swfIR) technique is offered by Jon Aldinger, Mark Huot, and Dan Mall. It applies to inline (cf background) images and uses JavaScript and Flash to swap out the original and deck it out with bling. It does more than we require—image rotation and stretching for example, and at first glance it certainly looked like the wrong tool for the job. I wondered, however, if we could use CSS positioning to overlay our text on top of the replaced images. It turns out you can:

swfir.jpg

Scoresheet:

Photo background: Supported (as an inline image!).

Gradient background: Supported (as an inline image!).

Four rounded corners: Actually you get 6! (you could potentially blot out the bottom border on the heading using a third positioned inline image—a real hack!).

Border: Yes (specified in JavaScript).

Drop shadow: Yes (specified in JavaScript).

Minimal mark-up: Requires insertion of two inline images.

Static mark-up: Mark-up edited to insert inline images plus box-specific script.

W3C validity: Yes. It does validate, but should I say "No" because it depends on Flash?

Anti-aliasing: Yes.

Small footprint: 25KB (24KB JavaScript and SWF; 1KB image overhead compared to master with original 2 background images.)

Graceful degradation: Acceptable (just) with JavaScript disabled.

Liquidity: Positioning depends upon fixed-width images.

Score: 7/12

ShadedBorder

Steffen Ruzee brings you ShadedBorder, a full-featured solution that uses only JavaScript:

shaded.jpg

Scoresheet:

Photo background: Supported.

Gradient background: Supported.

Four rounded corners: Yes.

Border: Yes (specified in JavaScript), but height on .sb-inner causes blue background to show through (why isn't this also an issue with the h4 background image?). Setting height to 0 removes the bar but also takes out the gradient! Admittedly, you could style the background to tone in better.

Drop shadow: Yes (specified in JavaScript).

Minimal mark-up: A headline with it's own style can be achieved with extra mark-up, and extra script in the head, and another script that must be inserted before the closing body tag. This makes it fatally flawed for use in a templated system like WordPress, IMHO.

Static mark-up: As above, mark-up edited at 3 points, including a necessary change from div class to ID.

W3C validity: Yes.

Anti-aliasing: Yes.

Small footprint: 9KB JavaScript.

Graceful degradation: Renders as per the master if JavaScript disabled.

Liquidity: Yes (comment out width on #cornered; not shown due to duplicate IDs).

Score: 9/12

SVG

Firefox 2 and Safari 3 can both display standalone Scalable Vector Graphics (SVG) images, an unloved W3C standard. They can't load SVG from CSS, however, making SVGs unusable as background images at this time. The option to use SVG in CSS hasn't gone beyond a proposal, with Wikipedia noting "the use of SVG on the web is in its infancy". It took me quite a few hours to get to grips with the examples in the 1.1 spec and create a valid and functional XHTML/SVG file for testing purposes. The basic idea is to create a bordered box with rounded corners, fill it with a gradient, and apply a Gaussian blur to a slightly offset box of the same dimensions—all with a few lines of XML. Here is our box using Opera 9.25 (Mac):

svg.jpg

Scoresheet:

Photo background: Supported in CSS, but you loose the rounded corners.

Gradient background: Supported without CSS via linearGradient.

Four rounded corners: Yes via rx on rect.

Border: Yes via stroke on rect.

Drop shadow: Yes via filter with feGaussianBlur, feOffset, and feMerge.

Minimal mark-up: Requires insertion of inline SVG image(s).

Static mark-up: SVG must (currently) be added inline; also necessitates DOCTYPE change and .xhtml file extension.

W3C validity: Yes.

Anti-aliasing: Yes.

Small footprint: 0KB (background image additional; gradient image not required).

Graceful degradation: No (Internet Explorer 6 and 7 choke).

Liquidity: Positioning depends upon fixed-width SVG images; resizing text size or browser window is problematic.

Score: 7/12

Update 18.03.08: Safari 3.1 adds support for SVG images in img elements and CSS images.

CSS3

CSS3, if it ever arrives, promises not only rounded corners but drop shadows and multiple background images too (oddly the draft spec doesn't mention gradients). Apple's Safari (available for Mac and PC) already includes support for such effects—but of course it's not valid CSS. You can preview CSS3 rounded corners here and here in Firefox or Safari 3. Here is our box using Safari-specific not-quite-CSS3:

css3.jpg

Scoresheet:

Photo background: Supported.

Gradient background: Supported.

Four rounded corners: Yes.

Border: Yes.

Drop shadow: Yes.

Minimal mark-up: Yes.

Static mark-up: Yes.

W3C validity: No, but only because the standard isn't yet established.

Anti-aliasing: Yes, but note anti-aliasing artefact in the bottom corners.

Small footprint: 0KB (background images additional).

Graceful degradation: Yes (non-CSS3 aware browsers see a plain box).

Liquidity: Yes.

Score: 11/12

Summing up

Which technique you choose ultimately depends upon what you're after and what you prioritise. There is no one "best" solution that fits all requirements. In terms of form and function CSS3 has to be the clear winner if one must be chosen, with a perfect score blown only by the fact that it isn't a W3C standard (yet). Herein lies CSS3's only significant yet overwhelming drawback: what good is it if the majority users can't see the effects? At the same time I'm not personally sold on any of the alternative methods. The end results may look good; it's how they achieve them that I don't much care for. Although a method validates it typically involves cheating the validator (seemingly JavaScript's raison d'ĂȘtre). Just take a look at the live links with Safari's Web Inspector (example).

Before I put a lid on this little adventure, as Jobs would say, there's just one more thing... what about jQuery? The jQuery library (included with WordPress and the K2 theme) can be extended to render corners, shadows, and gradients. If this article was Part 1, then that exposition forms Part 2. Coming soon.

10 responses to “The best way to do corners and gradients”


  1. Comment 1 David

    Hi Bruce,

    I went through (some) of the above reasoning in planning my site and went for the simple CSS 3 approach, but reining-in some of the effects to make it at least useable by other browsers than webkit. i.e. I didn't use an alpha channel transparency for overlays, actually I get tempted to occasionally, but where I do it doesn't matter - other than aesthetics :)

    Same with drop shadows, but I avoid them in my resizing 'livesearch' panel as the shadow tends to get 'left-behind' and they break the panel's edges.

    Opera will sometimes see the rounded corners and sometimes not (version dependant), using this method, but they have a nice SVG tutorial here to get around this issue, plus a neat bit about SVG gradients and other techniques.

    Interesting stuff - as usual - cheers.

  2. Comment 2 Bruce

    I'm itching to use some of that WebKit/ Mozilla draft CSS 3 stuff too David—but I've harped on about proprietary Microsoft code so often I couldn't help but feel hypocritical :-|

    As for transparent overlays at one point I did use opacity: 0.8; on my tabs in the header. I recently realized I could achieve the same effect and validate by creating a 1px black image in Photoshop and setting transparency to 65%. I just repeat this with background: url('opacity65.png') center repeat; and use conditional CSS to set background: none; for IE6.

    I love the drop shadow Brent is showing to WebKit browsers here. It works really well on my page too, but I've turned it off (as with text-shadow in the header). I have allowed myself one non-valid indulgence: the welcome box here is CSS 3 draft (using -webkit-box-shadow and -webkit-border-radius and because this CSS is inline it should be the only page on my site that doesn't validate!

    Just 2% of visitors to my site use Opera, so I don't both testing with it (although for all I know that 2% might represent my 2 regular readers!).

    SVG? Yeah, I tried Googling for info on corners and gradients with SVG and found so little in the way of real-world use I didn't think it worth pursuing.

    Update 08.02.08: SVG test cases added.

  3. Comment 3 David

    Ha pngs, I love em!

    However, much as I have used transparent pngs in the past (full 24 bit gloriousness), I am trying to eliminate them now. Still, for the moment I have the pngbehaviour.htc file from here to make Explorer behave a bit better. (I don't actually know how well it works, as I haven't looked through a Windows machine running IE.)

    My ie6.css file has the following in: img { behavior: url("pngbehavior.htc"); }

  4. Comment 4 Bruce

    I am trying to eliminate them now

    Why is that David? Something against PNG or design reasons?

    I don't actually know how well it works, as I haven't looked through a Windows machine running IE.

    I just fired up Parallels (with multiple IEs as here) and checked out your site: the WebFX .htc file isn't working. I also installed it, and tried setting the full path to blank.gif but no go. I suspect that catch is "[blank.gif] should be placed in the same directory as the web page using the behavior". As it was developed during 2001-2004 I'm guessing it's only suited to sites with static HTML. I use an image-specific fix as here.

  5. Comment 5 David

    Thanks Bruce - it's the 24 bit pngs that will go, pro tem, nothing against yer standard ones though :)

  6. Comment 6 David

    David is wondering why the Gravatars all suddenly have black backgrounds - a change at Gravatar HQ?

  7. Comment 7 Bruce

    the Gravatars all

    All? I only see yours on black (mine also uses alpha-transparency but is unaffected). I tried refreshing my Gravatar cache but yours is still black.

    Update: No, you're right. Bugger.

  8. Comment 8 Graham Smith

    Greetings,

    I was recommended your site after I pleaded for help on the K2 forum. I needed some advice on rounded CSS box corners and this chap sent me your links.

    Just been fiddling for a few hours as it's all new to me and finally, after some unexpected issues, finally have it working.

    I used your first example actually, but it works a treat for my purposes. So thanks very much for a great article and whilst I was here, I have been checking out your other stuff so much to read. It all looks great! :)

    Especially liking the photo album stuff, but that looks a bit involved for me right now.

    Thanks again, Graham

  9. Comment 9 Bruce

    Thanks for the feedback Graham—although that "chap" was actually me! And re your question about widget spacing, I ended up using the same trick on geotagicons.com.

    The "photo album stuff" is not difficult. It's more-or-less a default installation of Gallery 2, integrated into WordPress via an iframe (no misbehaving plug-ins required). And the photos get into Gallery direct from iPhoto like this.

  1. 1 Pages tagged "minimal"

Something to say?

Comments may be moderated (e.g. no commercial promotion), are subject to spam filtering, and should be relevant to this post—otherwise make contact.

Usable tags include <a href=""> <blockquote> <em>. Select any text and click to quote.