Professional Network Articles

yDSF - Robust CSS Drop Shadows

By Randy 'ydnar' Reddig: July 01, 2005

yDSF Demo Screenshot

Drop shadows are cool, but adding them to elements of a web page can be a pain. You can fiddle with background images, tables, pure CSS solutions, Internet Explorer PNG limitations, or fixed single-use shadows tied to an image and a particular background.

The latest release of TypePad has a new popup (or flyout) interface element which presents the user with a set of options or an expanded view of an object when clicked on. The flyouts are similar to the location bubbles used in Google Maps. They have soft alpha-blended drop shadows that scale with the size of the box. The drop shadows are implemented in valid XHTML and CSS, with no CSS hacks or JavaScript. We call it ydnar Drop-Shadow-Fu.

Besides filling the need of TypePad’s user interface, yDSF is good for floating or other positioned block-level elements where a drop shadow is desireable. This article will describe the CSS needed to implement this use case.

Example Files

Requirements

We needed drop shadows that would be as simple to add to a page as possible. With that in mind, yDSF was created to meet the following requirements:

  • Pure CSS (no tables)
  • As little extra markup as possible
  • Scalable to arbitrary width/height boxes, without special-case images
  • Best-of-breed display on modern CSS2+ browsers (Mozilla, Safari)
  • Reasonable fallback for Internet Explorer (5+)

Implementation

yDSF is comprised of some lightweight structural (non-semantic) XHTML markup and a few CSS classes.

The Markup

<div class="ydsf">
	<div class="inner">content</div>
</div>

Content inside the inner div can be any regular XHTML. Content elements with vertical margins may cause the drop shadow to render incorrectly. Usage of additional containers with borders or clearing elements might be necessary. For instance, both Mozilla and IE require a br element after a single img, but for different reasons.

The CSS

The yDSF CSS is structured for Internet Explorer (<= 6), with CSS2 selectors used for the additional attributes necessary for more capable browsers. There are two class selectors and two pseudo-element selectors:

.ydsf Selector

The .ydsf selector styles the container element. It has the background image (GIF for Internet Explorer, PNG otherwise) for the drop shadow. The base/IE code is as follows:

.ydsf {
	display: block;
	position: relative;
	margin: 4px -4px -4px 4px;
	background: url(shadow-grid.gif) repeat;
}

The .ydsf class also specifies a fixed-up margin to move the offset block element back to where it would normally be positioned in the absence of a drop shadow. To increase the visible margin around the .ydsf element, add to (don’t replace) the existing margins.

The CSS2 html>body .ydsf selector adds the soft 24-bit PNG drop shadow, and adjusts the margin for the difference in shadow width. The offset of the shadow is done in the shadow.png image. For this example, it has 4px of transparency on the bottom and right sides.

html>body .ydsf {
	margin: 10px -10px -10px 10px;
	background: url(shadow.png) right bottom no-repeat;
}

.ydsf:before and .ydsf:after Pseudo-Elements

CSS2 browsers use the .ydsf:before and .ydsf:after pseudo-element selectors to render the upper-right and lower-left drop shadow corners. They are rendered as block-level elements with content: " " and some negative margin hijinks. Both .ydsf:before and .ydsf:after share some common attributes, including inheriting the background image of .ydsf and block/layout attributes.

.ydsf:before,
.ydsf:after {
	content: " ";
	display: block;
	width: 10px;
	height: 10px;
	background: inherit;	
}

The upper-right drop shadow corner is described by .ydsf:before. It is absolutely positioned on Safari, and positioned via margins in Firefox:

.ydsf:before {
	position: absolute;
	top: 0;
	right: 0;
	margin: -10px 0 0 auto;
	background-position: right top;
}

The lower-left drop shadow corner is described by .ydsf:after:

.ydsf:after {
	margin: -10px 0 0 -10px;
	background-position: left bottom;
}

.ydsf .inner Selector

The .ydsf .inner selector styles the inner box element where the content sits. Like .ydsf it is divided into IE/base CSS and CSS2 areas. It mainly serves the purpose of offsetting the content back to the position it should be in as if the drop shadow was not present.

.ydsf .inner {
	display: block;
	position: relative;
	overflow: hidden; /* prevents margin leakage from child elements */
	left: -4px;
	top: -4px;
}

The CSS2 version is straightforward, except it uses negative margins instead of relative offsets to achieve the offset:

html>body .ydsf .inner {
	left: -10px;
	top: -10px;
	margin: 0;
}

Conclusion

With Internet Explorer 7 going into beta this summer, Microsoft may decide to support more of the CSS2 spec and hopefully parse and display the entirety of the yDSF drop shadow effect. If you can live with the IE6 and below rendering, or choose to omit the drop shadow entirely on that platform, yDSF is usable today.

This article (and technique) was inspired in part by some excellent precedents, including Sergio Villarreal’s article on A List Apart and Douglas Bowman’s sliding doors technique.

Trackback URL for this entry:

Trackbacks:

Six Apart
Makers of weblog software and services for individuals, organizations and businesses.
This website is powered by Movable Type.