Who’s that code snippet?
Straight from A-Tag 2025: A Pokémon-inspired guessing game for semantic HTML. Let's have fun with screen readers!
If you need a reminder on how screen readers can differ in output from each other, you have a side by side comparison of JAWS and NVDA right here:
Choose your Screen Reader!
It’s time to talk about the oh-so-dreaded screen reader testing. As already teased, braille displays peacefully coexist with text-to-speech (or TTS for short) screen readers. They are a staple for web access!
Game Setup
The game is simple: Listen to a screen reader snippet of the text and guess the semantic HTML used in the source code.
The test setup for all audio snippets:
OS: macOS Sonoma 14.5
Screen Reader: VoiceOver
Browser: Safari 17.5
And the test page: Codepen.io/YuriDevAT You can follow along with your own device to find the differences between macOS VoiceOver and your test setup.
Screen reader output can vary between screen readers, operating systems, and browsers, so it’s important to include the exact build information in your testing tickets.
Game start!
Who’s that code snippet #1
It’s <del>: The Deleted Text element and <ins>: The Inserted Text element! Often used to track changes and updates.
<p>“I choose you, ”</p>
<del><p>“Pikachu!”</p></del>
<ins><p>“Charmander!”</p></ins>
And it visually renders like this:
Who’s that code snippet #2
Trick question! It’s still delete and insert. But without the <p> tags around each sentence this time.
<p>
<del>Pikachu</del> <ins>Charmander</ins> was so happy to hear that.
</p>
And it renders like this:
Pikachu is visually crossed out, but VoiceOver doesn’t give this information. Instead, we get both pokémon. About as functional as catching Kyogre with a Master Ball: Effort for the aesthetics only.
A wild CSS :before pseudo-element appeared!
Why do they render so differently? What you don’t see in the pure HTML here (but those who have the CodePen open on the side might have guessed it!) is that our render includes a sprinkle of CSS:
del.styled::before {
content: '−';
}
ins.styled::before {
content: '+';
}
del > p, ins > p {
font-size: 2rem;
margin: 0 1.5rem;
}
The :before places a plus before insert and a minus before delete. When they are outside the p, each paragraph gets the corresponding styling. Neither are real text, but this macOS/Safari/VoiceOver combo still reads them out. Looking like an unordered list, without actually being a list. Wait, is that you, Ditto?
Who’s that code snippet #3
It’s the wannabe fighting-type Strikethrough element!
<p>I'm so <s>lame</s> cool.</p>
Unfortunately, this is common in e-commerce to display discounted prices. Emphasis and Strikethrough are both known to cause this problem with screen readers, so just remember that using <em> and <s> is like bringing a fighting-type team to a ghost-type gym.
Who’s that code snippet #4
Maybe an easier one? <abbr>: The Abbreviation element
I don’t know about you, but I first learned that it’s good practice to wrap any abbreviations with an <abbr>. Well, how times have changed. Ironically, the easiest way to make this screen reader friendly is to write a full expansion of the term on first use with the abbreviation in parentheses or include a glossary if you have that many on one page.
To screen reader users it is both inefficient and annoying to hear the same sentence twice. Nobody got time for that, we have better pokémon to catch.
<p>It's easier to feel <abbr title="Fear of missing out">FOMO</abbr> than feeling <abbr title="Joy of missing out">JOMO </abbr></p>
Who’s that code snippet #5
This is one you don’t see often in Latin-based content: the Ruby Annotation element. It’s most often used for displaying the pronunciation of East Asian characters, like Japanese Kanji in this example, but can be used for annotation other kinds of text too.
<div>
<ruby>こんにちは<rp>(</rp><rt>Konnichiha</rt><rp>)</rp>皆さん<rp>(</rp><rt>minasan</rt><rp>)</rp></ruby>
</div>
Your next step on the Victory Road:
Check out Julia’s latest blog post on HTML and CSS that I didn’t even know about before I started creating content in Japanese. It covers text orientation, writing mode, margin block for mixing languages, as well as our precious ruby.
For the Advanced Trainer: Mew, Mewtwo, the DOM & Accessibility Tree
In the last episode of the Accessibility Championships, we covered the basic to intermediate training strategies for building a strong accessibility testing lineup. If you need a quick refresher, visit the previous training ground before advancing to the next level: