Drop caps in the wild
By Nicholas Rougeux, posted on March 1, 2008 in CSS, Web
Anyone who's created drop caps on Web sites knows they can be challenging to say the least. Every browser displays them their own way, requiring a variety of CSS hacks or conditional comments to give them some semblance of what was originally designed. The other day, I came across an obscure variation of the :first-letter
inheritance bug present in IE that had me really scratching my head.
This post isn't meant to be a how-to on drop caps. Instead, it's a possible solution to a very obscure side effect of using them. Hopefully it will help others who may be scratching their heads in the future.
The problem
On the surface, creating drop caps is simple. All you need is the :first-letter
pseudo selector and a few styles to make text wrap around it. Making them work in Internet Explorer is a nightmare but once that's figured out, everything's great, right? Not quite…
I recently had the chance to revisit my initial attempt at creating the styles for the Children's Memorial Hospital Web site in Chicago. Part of the site's design are nice drop caps on various pages like the page on Government relations.
I was able to get the drop caps working well in most browsers—even IE 6 and 7—but things got strange when people tried to print the page. The screenshot shows the photo and callout on the right getting pushed down so it's overlapping the paragraph below it and creating a white space above it—very strange.
After a lot of testing and research, I came across the page I linked to above that describes a :first-letter
inheritance bug present in both IE6 and 7:
IE6, 7b3: A pseudo-element which sets its own em font-size 'inherits' the em-margin of it's undimensioned (non-layout) element. In the following example, the first-letter shows a 3em margin-left.
—pseudo-class, pseudo-element, pseudo-CSS: IE/Win bugs with :first-letter, :hover, & Co.
This seemed to explain what should have been happening when viewing the page in a browser but didn't explain why it was only happening when printing the page or viewing print preview. I still don't know exactly why it happens only when printing, but I know how to fix it for the most part.
The solution
The first step is to set the hasLayout property to true of the paragraph with the drop cap by setting its height to 1% with the Holly Hack. Doing this displaces everything below the drop cap paragraph instead of just the callout.
Next, the drop cap paragraph needs a negative bottom-margin
to pull everything that's been displaced back up to look normal. The amount of negative margin varies depending on the size of the drop cap and any leading or margin applied to the paragraph containing it. I haven't found a formula for determining that amount yet.
The result is these two lines added to the print stylesheet using CSS filters for targeting IE 6 and 7:
* html .dropcap { height: 1%; margin-bottom: -4.1em; }
* + html .dropcap { height: 1%; margin-bottom: -4.1em; }
(The first line is for IE6 and the second for IE7. The lines cannot be combined into a comma-delimited selector becuase IE6 can't parse it correctly.)
Why does this happen?
I'm not exactly sure why this happens but there are a few things I've determined from my testing:
- This occurs when the element with the drop cap is in a container with hasLayout set to true and is followed by a floated element.
- There needs to be at least one other element before the element containing the drop cap to trigger the inheritance bug. This can be either an inline or block element.
- Using Eric Meyer's Reset CSS to resest all default browser styling helps in determining the amount of negative margin needed (in addition to being a great starting point with styles in general).
- The
DOCTYPE
used doesn't seem to matter. - The negative
bottom-margin
doesn't have a negative affect when floats aren't involved (pun intended!).
I'm very intested in hearing others' thoughts on this. I'm hoping that I'm overlooking a simple fix for this and welcome any better suggestions or explanations of why this is happening.
I've set up a drop caps test case page for this obscure bug and will keep it updated as I learn more.