(ab)using box-shadow for design tricks

By <daniel@redwerks.org>

While converting various designer mockups into html and css one trick I’ve used a few time is the abuse of box-shadow, defined by the css3-backgrounds.

Remember that not every browser supports box-shadow. caniuse.com has a support table you can review. Remember that while I’m using box-shadow on it’s own here you also need -moz- and -webkit- browser prefixes for your box-shadow rules.

For my examples we’ll use a simple blue button as the base for most of the examples:

box-shadow at it’s most basic was intended to allow you to create shadows to block elements. There’s no ‘trick’ using it this way, but lets not leave it out:

Besides basic shadows I’ve found box-shadow useful for creating glows.

The fourth number to box-shadow defines a length the shadow should go out on all 4 edges. Using that in combination with a similar length fade and a colour matching the background colour creates a simple fading out effect. I believe it works best with lighter colours where it acts like a glow around the box.

box-shadow: 0 0 5px 5px <color>;

The primary trick I’ve used most is abusing box-shadow to create borders. In css a block may only have one border. Some of the buttons I’ve been given in mockups involve two borders and a gradient to get a really nice button effect. To create multiple borders I’ve found that the effect can be done by abusing box-shadow. You put together two shadows, on the top a 1px shadow over a 2px shadow both with no fade out creating the effect of two 1px borders. You can see what this looks like without shadow on the right.

box-shadow: 0 0 0 1px <inner-color>, 0 0 0 2px <outer-color>;

While using this trick it’s good to keep in mind what the button will look like in browsers without box-shadow support. In the case of these buttons by mixing together a border and box-shadow we can create a button that has multiple borders and a fallback that uses one of them. In this case I use the outer-color in the border and use an inset border for the inner color. But you can also do the opposite using a normal shadow for the outer color and making the inner color the fallback border.

border: 1px solid <outer-color>;
box-shadow: 0 0 0 1px <inner-color> inset;

You know those feedback tabs you see floating on the sides of some webpages? I’ve found you can create that effect in pure-css without the use of any images. Again we use box-shadow to fake an extra border. But this time we create 3 separate shadows on 3 separate edges to create 3 parts of one border to leave out one edge. I used an inset in this case as it seams an outset can create an effect where 1px on both sides of the button are white leading to a gap. This is horizontal but with a little use of css transformations you could twist it into a tab on it’s side.

{
	background-color: #333;
	border: 1px solid #ccc;
	border-bottom: none;
	box-shadow: 1px 0 0 #fff inset, -1px 0 0 #fff inset, 0 1px 0 #fff inset;
}

The example buttons I’ve used so far have been simple for example purposes. But that naturally betrays what you can really do. With the box-shadow double border trick, some border radii, and a gradient you can create a really nice looking button design. And this is all done on a single element with absolutely no images or redundant markup.

{
	background-color: #0099CC;
	background-image: -moz-linear-gradient(center top , #7BCCE7, #0099CF);
	background-image: -webkit-gradient(linear, left top, left bottom, from(#7BCCE7), to(#0099CF));
	background-image: -webkit-linear-gradient(top, #7BCCE7, #0099CF);
	background-image:    -moz-linear-gradient(top, #7BCCE7, #0099CF);
	background-image:     -ms-linear-gradient(top, #7BCCE7, #0099CF);
	background-image:      -o-linear-gradient(top, #7BCCE7, #0099CF);
	background-image:         linear-gradient(to bottom, #7BCCE7, #0099CF);
	color: white;
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	border-radius: 5px;
	padding: 7px 15px;
	-moz-box-shadow: 0 0 0 1px #7BCCE7, 0 0 0 2px #3EA4C4, 3px 2px 5px #ccc;
	-webkit-box-shadow: 0 0 0 1px #7BCCE7, 0 0 0 2px #3EA4C4, 3px 2px 5px #ccc;
	box-shadow: 0 0 0 1px #7BCCE7, 0 0 0 2px #3EA4C4, 3px 2px 5px #ccc;
}