Ultimate edges - rounded, drop-shadowed, bevelled and completely scaleable!
In a previous post
I explained a quick and easy way of adding rounded corners to a box
that used background masking. This is fine if all you want is a simple
rounded corner, but what if you’re after something more complex, like
shadows and a bubble effect in addition to the rounded
corners? This means dealing not only with the corners but also each
side of the box, and if you still want to be able to make that box any
size, you going to need a pretty kick-ass solution. And that’s what
we’ve got here.
This approach makes use of some extra DIVs placed at the top and bottom of the box content, so things will get a little more crowded code-wise, but it’s all been set out neatly so it’s clear what everything is for. There are 9 small images used too, since each side and corner requires a different graphic, and we’ve used one in the middle too to ensure continuity (we could specify a colour, but Safari appears to tint graphics slightly which means that colours and images don’t always match up).
Not only does this solution allow for a box of any size, but also any background. Because I have used 24-bit PNG images for all the graphics, the shadow will cover whatever is on the background, meaning you can place this box on top of absolutely anything, whether that’s a solid colour or a beautiful photo. Unfortunately this means it won’t work in IE6 or below, but neither does it like the positioning techniques I’ve used - so if you’re viewing this on IE6, upgrade! It is free after all…
The key to this technique is being able to float an object left or right and then use negative margins to shift it outside the parent object. Let’s look at the top of the box first as an illustration.
The top div is set to have background: url(top.png) and has its height set to the height of the image. This will create the top edge of the box. Next we add in the top left corner, specifying both width and height, and float it left; we’ve now got a corner placed on top of the top edge. We then give it a negative margin-left (of the width of the corner graphic) to shift it to the left of the left boundary of the top div. Sounds a little confusing, but the images below should help to explain what’s going on.
Adding in the right hand corner is exactly the same, except that we float: right and give it a negative margin-right instead. Here’s the code for the top:
- .top {background: url(top.png) repeat-x; height: 37px;}
- .corner {height: 37px; width: 37px;}
- .topleft {background: url(tl.png); float: left; margin-left: -37px;}
- .topright {background: url(tr.png); float: right; margin-right: -37px;}
...
- <div class="box">
- <div class="top">
- <div class="topleft"></div>
- <div class="topright"></div>
- </div>
- </div>
The bottom edge and corners are done in exactly the same way as the top, so just repeat with different image backgrounds.
The middle is where things get a little more complicated, as we want the box to be able to expand to any height too. Again, two DIVs are added before the main content starts, one for each side. This time, rather than floating them left and right, which is what appears to be the obvious solution, we absolutely position them with position: absolute. To ensure that they are positioned relative to the box and not the entire web page, make sure you include a position: relative to the container DIV. Remember that we’re adding these edges to the outside of the container box, so we’ll be using negative numbers in here too. The left edge is set to top: 0 (i.e. the top of the container), left: -37px (or whatever the width of your edge graphic), width: 37px (ditto), and bottom: 0 (i.e. the bottom of the container). This means that the height of the edge is determined by the amount of content in the box, so it’ll stretch nicely to fit whatever amount of text. It’s the same story for the right edge, so no surprises there.
- .middle {background: url(bg.png); position: relative; overflow: visible; padding: 1px; color: white;}
- .left {background: url(left.png) repeat-y; position: absolute; top: 0; bottom: 0; left: -37px; width: 37px;}
- .right {background: url(right.png) repeat-y; position: absolute; top: 0; bottom: 0; right: -37px; width: 37px;}
...
- <div class="middle">
- <div class="left"></div>
- <div class="right"></div>
- <h2>Title goes here</h2>
- <p>Here is some text. Hello world!</p>
- </div>
To see this in action, download this demonstration.
And that’s all there is to it. It’s neat, it’s infinitely scaleable, it can sit on any background, you can use any corner graphics you like, and it’ll work in all major new browsers. Oh, and it’s free too - I won’t charge you for reading this tutorial!
Matthew




