Accessible Drop Caps

October 22, 2019 ; 10 Comments

Since the early days of the web, when images could be floated and text would wrap around them, designers have wanted to bring drop caps onto the web.

Then we learned how terrible a pattern like <img alt="M" align="left">atthew is for users, and CSS introduced :first-letter , letting us believe all our woes were solved.

Edge cases aside, they mostly were and still are.

An Incorrect Pattern

I read a tip recently on how to make an accessible drop-cap using HTML, CSS, and ARIA. The pattern, however, relies on two bits of code to work. One bit is an ARIA role and another is an ARIA attribute, neither of which works for more than a sub-set of users.

<p> <span aria-labelledby="word--first" role="text" > <span aria-hidden="true"> <span class="dropcap">M</span>atthew </span> <span id="word--first" hidden>Matthew</span> </span> watched the storm, so… </p>

This is not robust (nor correct) for two key reasons:

In short, don’t use this pattern.

An Accessible Pattern

If you have to use this pattern, then simplify it by first getting rid of the invalid code.

We hide the entirety of our fake drop cap and truncated opening word with aria-hidden="true" . That will prevent a screen reader from announcing it, but will still display visually.

<p> <span aria-hidden="true" class="drop"> <span>M</span>atthew </span> <span class="visually-hidden" >Matthew</span> watched the storm, so… </p>

Then we lean on a proven set of styles to visually hide the word that we want screen readers to actually announce.

.visually-hidden { position: absolute; top: auto; overflow: hidden; clip: rect(1px, 1px, 1px, 1px); width: 1px; height: 1px; white-space: nowrap; }

No roles, no references to text elsewhere to provide an accessible name. However, if your CSS does not load (because the class is in an external file), you will have double display.

An Ideal Pattern

Use :first-letter . If you do not like the way your drop cap rests with the surrounding text, play around with line-height .

This degrades most gracefully of both options, and you do not need to force authors to use arcane HTML constructs. Nor do you need to write some scripts to create this HTML construct for them.

Using the original example, by setting line-height: .6 from an original value of 1 , I achieved an equivalent outcome as the other two options.

p:first-letter { font-family: "Playfair Display", serif; font-size: 5.5rem; float: left; line-height: .6; /* from 1 */ margin-right: 0.05em; }

Obviously there are cases where this may not work well. You will need to adjust the line-height for different typefaces and surrounding text styles. It may not work for other reasons as well, particularly if you require pixel-perfect cross-browser designs. But start from this simplest approach first, then consider the more complex HTML hackery for the exceptions only.

Obviously you need to test you effort in more than the default browser and screen reader on your computer. Test across platforms, rendering engines, and screen readers.

Comparisons

I made an example to demonstrate each of the three variations.

See the Pen MWWJmwE by Adrian Roselli (@aardrian) on CodePen.

Screen Reader

I grabbed the most popular screen reader to compare the three variations.

Sorry, your browser doesn’t support embedded videos, but don’t worry, you can download it. NVDA 2019.2.1 with Firefox 70.

VoiceOver on iOS and macOS generally handle the incorrect pattern without the pause. JAWS does reasonably well depending on browser. TalkBack pauses as in the example here.

Screenshots

How it sounds is moot to most designers if it does not look how intended. The good news is that each of the variations is consistent across at least 9 browser and platform combinations, which I show below.

Internet Explorer 11 on Windows 10.

Edge (not Chromiedge) on Windows 10.

Firefox 70 on Windows 10.

Chrome 77 on Windows 10.

Safari on macOS.

Chrome 77 on macOS.

Firefox Focus on Android 9.

Chrome on Android 9.

Safari on iOS.

Justin Gagne has written a post, Rethinking Accessible Drop Caps , where he also adds a block of alternative text to describe the drop cap style. I recommend against this in most cases, but there may be a special case where the style is integral to the content at hand, so it is nice to see the option.

I found a link in that post to a video by Ethan Marcotte, Creating Beautiful and Accessible Drop Caps (also embedded below) where he presents a revised version of his earlier drop cap advice in a digestable walk-through, which uses the two techniques I present above.

Sitting in the CSS Inline Layout Module Level 3 Working Draft are the properties leading-trim and text-edge , which promise to make text boxes easier to manage. This could impact how easy it is to style drop caps, for example.

An article on Medium (that is devoid of useful alt text, as is the default on Medium) goes into more detail: Leading-Trim: The Future of Digital Typesetting . I captured a still from an animated GIF in the post (which you cannot stop) that I think does a good job of showing what these properties affect.

Still of an animation from Leading-Trim: The Future of Digital Typesetting