Previously we looked at moving to jQuery, and then at the best way to do corners and gradients using a variety of techniques (Part 1). In this follow-on article (Part 2) I want to share how jQuery can be extended for similar cornering, gradient, and drop shadow visual effects. Although my JavaScript ability is not much beyond "cut and paste" the idea here is to share how easy it is to create these effects for other folk possessed by similar (in)ability.
Situation recap
In Part 1 we explored various ways to make rounded corners, comprising one or more of JavaScript, CSS, Flash, and SVG. Ditto for drop shadows. Implementing a gradient was restricted to the use of background (or inline) images, or to SVG. There are a few more tricks we might try for gradients:
- We could load a transparent PNG as a CSS background and vary the fill colour on the container to allow for a multitude of colour-graduated boxes without further image editing (see this ALA article);
- Unfortunately the CSS 3 draft as of this writing doesn't include background gradients, but you might be able to fake it using border-color;
- We could use JavaScript effects libraries.
It turns out we can use JavaScript to create our corners and drop shadows too. There's also a plugin for using curvyCorners with jQuery that more than halves the standalone curvyCorners code size.
Extending jQuery
While there are some basic effects (hide, toggle, slide, etc.) and manipulation options in the jQuery core API, jQuery UI is a bolt-on library of interactive controls that deal with mouse interaction (e.g. resizing, dragging) and other "user interface" extensions. As of this writing the jQuery documentation is incomplete and the developers in the process of transitioning visual effects formerly included in jQuery UI to a new sister library called jQuery Enchant. The controls (also referred to as core interaction plugins, UI widgets, or components) are themselves are almost invariably dependent on other jQuery extensions—needing at least the Dimensions plugin.
So jQuery needs to get its act together in respect of naming conventions, but perhaps this is more indicative of active development rather than lack of direction? I guess jQuery UI/ Enchant are to jQuery as script.aculo.us is to Prototype. In a nutshell we're saying that with some jQuery code that in turn requires a bit more extra code in order to work, in addition to the code that is "jQuery" itself—we can create visual elements like drop shadows! jQuery is thus readily extendible; to use these extra bits of code you just need to load the relevant add-on script in your document head, after having loaded jQuery itself. A picture may help:

Test cases
I've used the same basic test box from Part 1, so our core document structure looks like this:
<!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>
<title>jQuery test cases</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="jquery-1.2.3.pack.js"></script>
<script type="text/javascript" src="jquery.dimensions.min.js"></script>
<script type="text/javascript" src="jquery.corner.js"></script>
<script type="text/javascript" src="jquery.gradient.js"></script>
<script type="text/javascript" src="fx.shadow.js"></script>
<style type="text/css">
...
</style>
<script type="text/javascript">
// <![CDATA[
$(document).ready(function() {
...
});
// ]]>
</script>
</head>
<body>
<div class="className">
<h4>Lorem ipsum</h4>
<p>Lorem ipsum dolor...</p>
</div>
</body>
</html>
With all the necessary libraries loaded we can start adding effects to our div by calling them within $(document).ready() (in place of ... above).
Download the test files here (.zip archive, 27KB).
Here is the live link.
Case 1: Round corners
If you wanted to use fancy images to produce round corners yet avoid extra mark-up, you could use this technique. Alternatively use no images at all via the jQuery corner plugin, available here. The plugin supports a variety of corner types and borders as you can see in the demos. The following call will add cornering with a radius of 20px to a div with the class .cornered:
$('div.cornered').corner("20px");
This will have the following effect on our test box:

Case 2: Gradients
The Element gradient plugin, available here, will fill an element (e.g. div) with a linear gradient of specified direction (horizontal or vertical only) and opacity. It requires the Dimensions plugin. The following call will add a vertical gradient from black to white with 40% opacity to a div with the class .gradient:
$('div.gradient').gradient({ topcolor: '#000000', bottomcolor: '#ffffff', horizontal: false, opacity: 40 });
This will have the following effect on our test box:

Note that you can't shorten the hex-code (it must be #ffffff not #fff for white, for example).
Tip: If you leave the gradient as black to white with some opacity you can create colour gradients much more easily but changing only the background colour of the container. This is a jQuery version of the ALA super-easy blendy backgrounds trick.
Case 3: Borders
Back to the jQuery corner plugin; it can also do borders using nested elements i.e. one rounded box inside another. So our mark-up could be edited thus:
<div class="xtra">
<div class="border">
<h4>Lorem ipsum</h4>
<p>Lorem ipsum dolor...</p>
</div>
</div>
But we don't want to edit our mark-up do we? We don't have to.
Tip: We can make use of .wrap() to inject the extra container into our mark-up on-the-fly with JavaScript.
The following calls will add a wrapper div with the class .xtra to our box, then proceed to round our inner box (.border) with a radius of 15px, before padding .xtra with 5px of "border" (whitened with CSS on .xtra) and rounding with a 20px radius:
$('div.border').wrap("<div class='xtra'></div>");
$('div.border').corner("15px").parent().css('padding', '5px').corner("20px");
This will have the following effect on our test box:

Case 4: Drop shadows
In researching this article I came across three ways to create drop shadows using jQuery:
- Shadow is an extension that uses tables with multiple rows subject to CSS styling including varying opacity to create a drop shadow illusion;
- A method that uses images and "onion skin" CSS added via .wrap() to add a drop shadow;
- UI/Shadow.
UI/Shadow, available to download here, is being folded into the yet-to-be-released jQuery Enchant library. It wraps your element in nested divs and uses opacity to create the shadow effect. It also requires the Dimensions plugin. The following call will add a drop shadow to a div with the class . dropshadow:
$('div.dropshadow').shadow({ color: "#444", offset: 5, opacity: 0.2 });
This will have the following effect on our test box:

Combining effects and liquid layouts
As you can see while the effects in cases 1–4 work well enough on their own, they sadly don't play together very well (see Case 5). Whether this is a limitation in one or more of the plugins, or in my scripting know-how I'm not sure.
It is possible to create a rounded box with a border that adjusts to change in text size or window width, but using an image to render the gradient (see Case 6). Because the Dimensions plugin employs absolute positioning, effects that use it (gradients, drop shadows) will "detach" from their elements if you try resizing your browser window or changing text size (see the effect on cases 2, 4, and 5).
The final score
To be fair I guess we should use the same scoring system to evaluate jQuery against the other methods we explored in Part 1.
Scoresheet:
Photo background: Supported.
Gradient background: Supported (as image or scripted).
Four rounded corners: Yes.
Border: Yes (without extra mark-up).
Drop shadow: Yes (without images).
Minimal mark-up: Extra containers in mark-up can be avoided with .wrap().
Static mark-up: Mark-up edited to insert box-specific script.
W3C validity: Yes.
Anti-aliasing: No.
Small footprint: 29KB for jQuery plus 19KB for add-on libraries (background images additional). Of course if you're already using jQuery you need only consider the additional size of any add-ons (e.g. shadows for 6KB).
Graceful degradation: Renders as per the master if JavaScript disabled but liquid layouts may cause problems if width is set on containers added with .wrap().
Liquidity: Yes, with the proviso that you avoid Dimensions-reliant effects.
Score: 9/12 (probably less, because of problems combining effects)
Not enough to de-throne CSS 3 which scored 11/12, or 12/12 if it were a standard. But CSS 3 isn't here yet and won't be widely supported by all major browsers for some time. jQuery is here, however, and JavaScript is widely supported.
Upon reflection there's something to be said for the elegant simplicity and refined geometry of straight lines and sharp corners. This is how the Dwarves would choose to build websites, leaving curves and soft edges to the Elves. So the ultimate question, really, is do you relate more to Gimli or Legolas? Your answer to that, Middle-earthlings, will decide the direction you should take ;-)









In FF2 when resizing the test page the shadows and gradients remain in the same place... it is weird.
Cheers.
Not weird Andrei, and not just in Firefox:
I am completely non-technical. I see this example uses divs to operate on. Is it possible to specify ul, li or p or others to acheive the sanme effects? Somewhere I've seen some jquey extn. that allows this.
Yes it is not only possible Rodger, but extensions are not needed since it's part of the API. You don't need a div container although it may be more convenient if you are applying effects to more than one contained element, as in the above examples. I used jQuery to selectively apply CSS3 effects to an element (h1), a paragraph class, as well as div by ID here. And JavaScript visual effects to a single list item (li) anchor here, and an entire unordered list (ul) here. There's a list of CSS selectors supported by jQuery here.
Thanks Bruce, I see someone here has another (reduced?) version which has some problems.
Whilst my immediate application is in a fixed page will this one work in a flexible page?
Rodger, it depends very much on what you mean by "this one" ;-)
Note my scoresheet above says "Liquidity: Yes, with the proviso that you avoid Dimensions-reliant effects." Here meaning gradients and drop shadows. For other (non-jQuery) techniques that play nice with fluid-width pages, see the scoresheets in the companion article to this one. And if you want rounded corners with borders, gradient backgrounds and drop shadows with no extra mark-up and no JavaScript plus guaranteed liquidity see here—and convince everyone to use Safari :-|
Whaddayaknow?
I'm looking into a little tab solution. Experience a little problem with jquery. Turn back to google. Boom. There's Bioneural in the top search results, talking about jquery !
Btw. The issue is a non-transparent top left tab corner. I must be one of the first people trying tabs on a non white page ;) Even after applying transparency to the standard png tab's corners. Must be something bleeding through, but can't figure it out. So I bypassed it.
Not sure this is relevant to the entry though. But, will put the check mark anyway ;)