Quantcast
Channel: WCAG – Adrian Roselli
Viewing all articles
Browse latest Browse all 35

Accessible Drop Caps

$
0
0

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:

  1. First, there is no text role in ARIA. You can confirm by checking the full list of roles in ARIA 1.1. Nor is it in the roles list in the ARIA 1.2 Working Draft. As Scott O’Hara points out, this only works in WebKit browsers, which is why this role works if using VoiceOver with Safari on a Mac.
  2. Second, aria-labelledby generally does not work on <span>s. Instead, aria-labelledby is meant to provide an accessible name for interactive elements, landmark roles, widget roles, and <iframe> & <img> elements. The Using ARIA document from the W3C provides more detail, though you can find a more readable explanation from The Paciello Group. Further, using aria-labelledby in that way will be against the spec in ARIA 1.2 (see Prohibited States and Properties).

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.

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.

Viewing all articles
Browse latest Browse all 35

Trending Articles