Drop caps, first-letter and Firefox

I have been experimenting with the :first-letter pseudo-element to try and write up a tutorial on using first-letter, adjacent selectors and @font-face to produce drop caps and I have run into a problem in the form of Firefox. Because you need to apply the property float: left to stop first-letter being an inline element and Firefox applies different rules to floated :first-letter pseudo-element than the other browsers, making it difficult to vertically align a floated :first-letter pseudo-element and the the remaining text.

The specs for :first-letter pseudo-element state:

These are the properties that apply to :first-letter pseudo-elements: font properties, … ‘line-height’, … margin properties, padding properties … UAs may apply other properties as well.

Width and height are not properties that have to be applied to first-letter. Only the WebKit family (Safari, Chrome etc.) apply these properties. The main issue is line-height which could be used to control the vertical size of the first-letter pseudo-element, as according to the specs.

To allow UAs to render a typographically correct drop cap or initial cap, the UA may choose a line-height, width and height based on the shape of the letter

Internet Explorer, Webkit and Opera have chosen not to apply line-height and unless one is specified, a :first-letter pseudo-element will inherit line-height from the parent element. Firefox has chosen to apply a line-height to all first-letter elements equal to the height of the element and you have no method of changing it. This automatically aligns the top of the floated :first-letter pseudo-element in the parent block element.

Because the line-height is the height of the type, you get different line-height for different characters eg a, t and p. Which makes it virtually impossible to use lower case letters to produce drop caps like effects.

So you need to reduce the line-height of first-letter to the cap height of your chosen typeface then use margin-top or padding-top to vertically align the top of first-letter with the top of the remaining text. Not only is this more complicated than just changing line-height, you need to do two calculations instead of one. Internet Explorer applies margin and padding to floated :first-letter pseudo-elements differently than other browsers. By fixing the :first-letter pseudo-element in place after applying line-height then applying margin and padding to it, which does not effect surrounding elements.

:first-letter pseudo element

Five different browsers rendering floated :first-letter pseudo-elements with slightly different properties. Chrome produces the same results as Safari. Note IE8b2 does strange things to backgrounds both colour and images of the:first-letter pseudo-element.

So to get a cross browser drop cap effect using :first-letter pseudo-element that vertically aligns, you need to apply float: left, then find the height of the typeface cap height, reduce the line-height to that, adjust margin-top so it aligns correctly in Firefox and in Opera or a WebKit browser, and then using conditional comments for an IE only stylesheet remove margin-top and change line-height to correctly vertically align the type.

It would of been a lot easier if Mozilla Corporation and Microsoft read the CSS specifications the same way as everybody else and applied the same rules.

5 Responses to “Drop caps, first-letter and Firefox”

  1. Ann Arbor Web Designer Says:

    Conformity is not the key on a diverse resource like the internet.

  2. Ann Arbor Michigan Web Site Design Says:

    Long time since you wrote a new post. Have you abandoned this site?

  3. John Says:

    “Conformity is not the key on a diverse resource like the internet.”

    Yeah but standards should be applied. Its ridiculous trying to alter code to suit several different browsers.

  4. Wistful Writer Says:

    Hey, just wanted to stop by and say thanks! I was fiddling around with @font-face and dropcaps recently and was shocked to see what was right in Firefox was way off in both Chrome and Safari. Your tips got everything working pretty well, thanks a bunch!

  5. Alex B Says:

    I wanted to add a thanks for this article and a lament that the bug still exists, though I’m not sure which browser’s “fault” it is. I’ve tried your advice above and, though it looks OK, I still find a variance of about 10px between different browsers. This issue is further complicated by the font you’re using (since one browser may be using the .woff and another the .otf), and whether you already have a locally cached font. IE9 seems to display things differently again.

    Another description of this bug which must plague other people trying to do nice, clean typography is here: http://dev.l-c-n.com/CSS3-selectors/browser-support.php#n4

    I’ve opted to do wrap the first character in a span as follows and abandon :first-letter completely:

    span.dropcap {
    float: left;
    font-size: [whatever]px;
    line-height: [measured caps X height]px;
    margin-top: [play according to font];
    margin-bottom: [negative value in case the top margin pushes the text below the drop cap onto the next line]]