yDSF - Robust CSS Drop Shadows
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.



Comments