Cross browser drop caps with CSS

The other day I read Laura Franz’s excellent in-depth article on Drop Caps: Historical Use And Current Best Practices With CSS over on Smashing Magazine, and it prompted me to look into adding this to my site as I was intending to do so anyway. Naturally there were some issues.

In Laura’s article, all of the looked at methods caused issues with screen readers as wrapping a separate element around the first character of a paragraph caused the screen reader to read the letter out separately which isn’t ideal. The only method that didn’t do this was using the CSS :first-letter selector as naturally the HTML isn’t altered at all.

That was the deciding factor for me. I had to get this to work cross browser.

Browser issues

Laura mentions that using her p:first-child:first-letter selector caused placement issues across browsers. The examples she displayed sample rendering images of were Firefox (this selector actually didn’t work at all for me in Firefox 11, it seemed to ignore two pseudo selectors together), a WebKit browser (I think – since I had the same results initially but Laura doesn’t name the specific browser), Opera Mini 5.1, Mobile Safari 4.0.5 and versions of Internet Explorer 7.

Like Laura, I initially styled the drop caps to work with Firefox, and then checked with other browsers. I also made some tweaks in an attempt to get things working on other major browsers without breaking the original (i.e. on Firefox).

It must be noted that Laura tested exhaustively, with 82 different browser and operating system combinations. My testing was nowhere near as thorough.

A solution

I’ll simply lay the code out here for you to see, although you’ll also see it in the CSS of this site:

p:first-letter {
	margin:11px 0 -5px 0;
	padding:0 .1em 0 0;
  *line-height:1em; /* IE7 Only */

I had issues with WebKit browsers which had the drop cap displayed too high and adding extra padding to the end of the letter box. By setting both the height and line-height of the element, this solved that issue, and Firefox appears to be unaffected by these.

Both Internet Explorer 9 and 8 also displayed the element too high plus had the same “extra bottom padding” issue as WebKit. The “fix” for WebKit had no effect in IE, however I was initially using ems to specify the margin values, and changing to px and doing some tweaking fixed that issue. A negative bottom margin also solved the IE “extra bottom padding” issue and all was well there.

I tested it on the iPad 2 and an iPhone, and it displays just fine, as it does on the default Android 2.2 browser. It also displays correctly on the latest version of the Opera desktop browser, version 11.62.

Known issues

IE 7 does still display it a bit too high, but either an IE7 specific hack or stylesheet would fix this (it’s a margin issue). Opera Mini still has the same issue as Laura reported.


And that’s it really, relatively simple in the end, although not 100% cross browser compatible (but sadly what is?).

If you have any thoughts on this method or indeed how to fix some of the issues mentioned above, please do let me know!

Update –

I’ve updated the code above to fix Internet Explorer 7. As it only required a change to line-height I decided to use the asterisk hack to target IE7 only.

Note that since first-letter isn’t understood by IE6, this browser renders it as normal.