CSS Widget (rounded corner, gradient, drop shadow) / 20-Jul-2009 / 3 comments

I have recently had the task of developing a drag and drop widget style application. To make things more exciting the designers managed to include all three CSS nasties in one widget.

  1. Gradiented background (on both the widget and main screen)
  2. Rounded corners on the Widget
  3. Drop shadow on the Left and Bottom edges

The widgets are also fully resizeable, so no fixed size images. After a bit of searching around I didn't find any particularly good solutions, and I also wanted to steer away from using any superfluous JavaScript. The solution I came up with uses only CSS and four images, its standards compliant and works across all the browsers (with slight degradation on IE6)

Below is an image of what we are trying to acheive

Application design

I have created a zip file which contains a working demo of the CSS, and can be downloaded here zip icon

Creating the Images

The first step in the process is to create the source images. Using Photoshop its pretty easy to knock up a quick widget design. The plan is to create as small a widget as possible, we will then cut out the necessary slices and take an image of the whole widget.

Widget with Slices

Widget with slices marked out

The widget should be wide enough that the corners have at least 5 pixels of space between them, and high enough that the whole gradient is displayed with a small amount of solid color at the bottom and top. If you are using Photoshop this image can be created quite easily with the 'rounded rectangle tool'. Then using layer styles apply a gradient overlay, drop shadow and an inner glow to get the 1px outline. Save the image as a transparent PNG

Using the slice tool cut out the necessary slices as show in the above diagram. The three slices will be used as follows

  1. Background Gradient, this is the gradient that will be applied to background of the widget, it will be repeated across the x-axis
  2. Right Shadow, this image contains the alpha fade for the right hand shadow and also the border, it will be repeated across the y-axis.
  3. Bottom Shadow, same as the right shadow but for the bottom, it will be repeated across the x-axis.

The Markup

Now that the images are ready we can start creating the html, each widget will contain the markup shown below. The 'content' div will contain any markup for the content of the widget, the rest we are going to use for styling.



<div class="widget">
    <div class="content"></div>    
    <!-- shadows -->    
    <div class="topLeft" />    
    <div class="topRight" />
    <div class="bottomLeft" />
    <div class="bottomRight" />
    <div class="left" />
    <div class="right" />
    <div class="top">
        <div class="inner" />
    </div>
    <div class="bottom">
        <div class="inner" />
    </div>
</div>

The CSS

The next step is to apply some css, I wont explain too much as the code should speak for itself. In brief, the top and bottom divs will be solid colour and should blend seamlessly into the gradient background of the main widget. To ensure the widget resizes correctly without any overlap we use the 'inner' divs on the top and bottom, these provide padding to make space for the corners.

Widget with Divs marked out

Widget with marked out Divs

IE6

Presuming you decide to support IE6 you may have a preferred method of dealing with transparent PNGs. I for one try to avoid using the PNG transparency hack which can hamper performance especially in a fully blown web app. The option I would normally swing towards is to use a conditional stylesheet, and then redirect the background image to an 8-Bit PNG. The 8-Bit PNG can not support alpha transparency so no drop shadows, it will however support pure transparency with a feathered edge. To cut down on the amount of files needed for this demo I am just using the underscore hack (e.g. _background:transparent;)


	/* Border Color #A6BAE5 */
	/* Top Gradient Color #6D83CA */

	#container {
	    height:400px; width:100%;
	    border:none;
	    background: #6076BE url(images/container_background.png) repeat-x scroll 0 top;
	}

	#widget1 {
	    position:absolute; top:100px; left:100px;
	    width:200px; height:220px;
	    z-index:3;
	}

	#widget2 {
	    position:absolute; top:20px; left:150px;
	    width:250px; height:400px;
	    z-index:2;
	}

	.widget {
	    width:200px; height:150px;
	    background: #6D83CA url(images/background.png) repeat-x 0 bottom;
	    min-height:232px;
    	}

	.widget .content {
	    position:absolute; top:0; left:0; z-index:100;
	    width:100%;
	}

	.widget .content .inner {
	    padding:10px;
	    text-align:center; color:#fff; 
	    font: 0.75em 'arial', sans-serif;
	}

	.widget .topLeft {
	    position:absolute; top:-10px; left:-1px;
	    width:10px; height:10px;
	    background: transparent url(images/widget.png) no-repeat top left;
	    _background: transparent url(images/ie6/widget.png) no-repeat top left;    
	}

	.widget .topRight {
	    position:absolute; top:-10px; right:-4px;
	    width:14px; height:10px;
	    background: transparent url(images/widget.png) no-repeat top right;   
	    _background: transparent url(images/ie6/widget.png) no-repeat top right;  
	}

	.widget .bottomRight {
	    position:absolute; bottom:-13px; right:-4px;
	    width:14px; height:13px;
	    background: transparent url(images/widget.png) no-repeat bottom right;   
	    _background: transparent url(images/ie6/widget.png) no-repeat bottom right;   
	}

	.widget .bottomLeft {
	    position:absolute; bottom:-13px;  left:-1px;
	    width:10px; height:13px;
	    background: transparent url(images/widget.png) no-repeat bottom left;
	    _background: transparent url(images/ie6/widget.png) no-repeat bottom left;
	}

	.widget .top {
	    position:absolute;  top:-10px; left:0;
	    width:100%; height:10px;
	}

	.widget .top .inner {
	    margin:0 10px 0 9px;
	    height:100%;
	    background: #6D83CA;
	    border-top: solid 1px #A6BAE5;
	}

	.widget .bottom {
	    position:absolute; bottom:-13px; left:0;
	    width:100%; height:13px;
	}

	.widget .bottom .inner {
	    margin:0 10px 0 9px;
	    height:100%;
	    background: transparent url(images/bottom.png) repeat-x bottom left;
	    _background: transparent url(images/ie6/bottom.png) repeat-x bottom left;
	}


	.widget .right {
	    position:absolute; top:0; right:-3px;
	    height:100%; width:3px;
	    background: transparent url(images/right.png) repeat-y top right;
	    _background: transparent url(images/ie6/right.png) repeat-y top right;
	}

	.widget .left {
	    position:absolute; top:0; left:-1px;
	    height:100%; width:1px;
	    background:#A6BAE5;
        }

Below is the final result, which with a bit of luck should look good on whichever browser you are using.

Widget 1
Widget 2

comments

thanks / 7-May-2010 / Stefano

My goal was a rounded box with shadow and thanks to you now is made ;)

Don't really understand / 19-Aug-2009 / Mark

Hey dandy i tried to figure out how you sliced the rounded corner image with a gradient but i .... my challenge is cutting to your description of the"Right shadow" and "Bottom shadow"

css-rounded-corner / 16-Aug-2009 / francky

Hi Andrew,
Just passed by and didn't dive literally into the code, but it looks fine. It's a pity your zip file doesn't have a html-page to see it working, maybe you can add this?

Surprise: it seems your solution is a lot like mine! :-)
- Oct. 2005 I published the universal "Liquid round corners" method, also css and image only; self adapting to window-size, font-size, etc.; support for transparency; cross browser; only 1 small image needed; and adjustable for self made borders (2 small images needed). It is hard to Google because of an awful lot of (mostly the same) partial solutions...
Have a look at: http://home.tiscali.nl/developerscorner/liquidcorners/liquidcorners.htm.
Some examples you can find in the "Liquid Corners Playgarden": http://home.tiscali.nl/developerscorner/liquidcorners/liquid-corners-pla....

Cordially,
francky kleyneman

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

© Andrew Polhill 2008 - 2009