How I improved this site for Screen Readers
Today, I updated the homepage to be screen-reader friendly. I feel relieved (a bit) of
being a fraudster
I had positioned the site to teach accessibility (a11y). Yet, that page isn't accessible to blind users. Or anyone who listens via Assistive Technologies. How ironic!
Here is an audio of how the banner sounds before the update. Listen. I doubt you'll understand because of the noise.
Anyways, after the update, it sounds clear and understandable. Despite no visuals.
Note on Presentation Tools
The screen reader used for all presentation on this page is NVDA version 2021.03.01. Along with Google Chrome Browser version 99.0.4844.51. These are made on Windows 8.1 OS. If you notice anything odd with another device or app, kindly send me a message on Twitter @toheebdotcom
How I conveyed the content with no noise
weeds are unwanted plants?
noise are unwanted speech.
The characters I used for composition became that unwanted speech. Hence, the noise. The video below shows how the noise came to be for the banner before the update. (You heard the audio earlier.)
Why are the design characters read out?
Reason is, I used CSS pseudo-elements
::after to insert content into the DOM. Contents meant for presentational purpose. Now, screen readers communicate these CSS contents like HTML content.
As if that's not enough, pseudo-elements in an heading are read out as separate headings. And some design characters like
y may be confused as the 3 letter word
why. All these noise could go away if I mute them.
We can use the CSS declaration
speak: none to avoid screen readers reading out content, but there's little to no support for this.
The best way to hide content from screen readers is to declare
aria-hidden="true" on the HTML element.
Since I can't hide the elements I appended the design characters to, I used a new element instead.
While I can insert this content into the HTML element, I preferred via CSS. Because the choice of these characters depends on their content style.
Thus: an empty element with
aria-hidden="true" for a pair of characters per content segment.
This result in clearer communication of the banner since the design characters are not read out. Meaning, no noise.
The video below shows the main content being read out after the screen-reader update. This is the current state of the site.
While this section focused on hiding design characters, there are times we'll need to communicate CSS styles. The next section focus on one such moment.
How I communicated Styles that aid content deliverability
The design style influences the content structure. So, I deemed it necessary to hint screen readers.
Because, the page's header isn't the typical logo + nav menu. Nor is the footer a bunch of links. They looked like the front and back cover of a book respectively. Same as the table of contents.
Moreover, owing to an earlier design feedback, I introduced a Dedication section to emotionally connect with my target audience. And, an Introduction section to buttress the essence of the site.
Hence, like a physical book, I have the following parts:
- Front Cover
- Front Matter
- Back Matter
- Back Cover
The Front Matter consists of the Dedication, Introduction, and the Table of Contents. While the Back Matter consists of the Case Studies, and Resources. Along with the Front and Back Cover, they make the homepage.
Visually, I plan to constrain each part by a fixed width and height. And, provide the ability to flip through them like the pages of a book. For now, I demarcated them with an hyphen.
Audially, I marked up these regions with landmark elements and assign the book-region's name as the accessible name. That is...
Banner landmark has the label
Main landmark has the label
A generic landmark has the label
Contentinfo landmark has the label
In addition, I modified the title to include the term
Book. This way, the terminologies won't sound strange when screen readers navigate by landmark.
Below is a video highlighting each landmark of toheeb.com.
The simplified HTML for the landmarks look like below.
I nested Back Matter inside of Front Matter because both content are the main content of the page. Since Landmarks have flat hierarches, this parent-child relationship will be conveyed as if they were siblings.
Despite my nesting, the document outline says different, as intended. Thanks to the heading & sectioning elements.
How I created the Document Outline
Apart from the landmarks, headings are another way for users to navigate the document. According to this Screen Reader Survey by WebAIM, 67.7% of users surveyed navigate via landmarks compared to 3.2% via headings. Hence, the need for a well-outlined document. Which is also useful for search engine crawlers.
A convention is to use an
h1 element for the document's title. And, a rule is to avoid skipping heading levels.
Thus, I started the page with an
h1 for the document's title which is the front cover's title. Other book parts start with an
h2 heading. Each content category uses an
h3 while each featured article is an
The video below shows how HTML5 Outliner outlines the page. Notice that both the dedication and back cover's title are visually hidden. Because, they are visually unnecessary.
How I structured the Content Categories
For the Table of Content, I structured the categories as an ordered list. Even though, it didn't use ordinal values for the design.
At first, I doubted if using a list block for the content category was necessary. I went ahead because the total count of 3 simplifies the learning objectives for the user. This supports the goal of the site.
ul because the order matters. But I don't need numbers as list markers in the design:
Now comes a challenge. Removing markers of a list item removes its semantics.
One solution is to use a non-breaking space. Another is to re-instate the list block with
role="list" though it is against the first rule of ARIA.
What I did is to replace
::marker pseudo element with a visually hidden
::before counter. No violation of ARIA rule. No need to alter the markup.
Starting with the markup, I used an
ol element with an accessible name of
content category. Each list item has an element hidden from Screen Readers that contains the nominal value used as list marker.
::marker of a list accessibly with only CSS, we'll re-instate the counter using
::before selector that can accept visually hidden styles. (Since
::marker selector has limited CSS declarations that can go within it.)
Here's a video highlighting how the List Blocks of the Table of Contents are read. When there's no content within a category, the elipsis reads
No articles yet. Otherwise, it reads
More articles coming soon. (I'm looking forward to having each category with a complete set of articles. 💪)
Now that the table of content sounds good. How easy is it to reach it?
How I improved Reachability to the Dynamic Content
When you take a look at the whole page, the dynamic part is the Table Of Contents (TOC). Other parts are static contents conveying the TOC's value. Upon reading those static contents, your focus changes to getting new content at the TOC. Having to scroll past them, everytime, can piss you off.
Navigating to the TOC is easier for screen readers. The first content you'll hear is a skip link to the table of contents. That's because I included a visually hidden skip-link at the top of the page.
Keyboard users are also 1 tab away to access the skip-link. Since it isn't hidden to a tab's focus.
For touch users, you can swipe fast and hope to stop exactly at the TOC. Or pan slowly across the header, dedication, and introduction till you get there. Same for mouse drag. Both has room for improvement.
One thing though, I can make the skip link visible for everyone. But, to touch & mouse users, that is still a boring repetitive step.
Upon page load, Screen readers and Keyboard users' interaction starts at the top of the page. But pointing device such as Cursor, or thumb may be at any part of the page. It becomes a boring routine if you have to move the cursor to the skip link – every – single – time.
My first counteraction is to use an accordion for the introduction. This won't remove the headache but makes it easier to get to the TOC. On the flip side, it takes a click to read the contents of the introduction. This is a nice tradeoff considering I want the page to be less pitchy.
How about 99% faster? It is possible if I could avoid the top entirely. Not to delete but jump them automatically. By user's request of course.
The way I did it is to store the user's preference and automate a scroll to the TOC whenever the page loads. I like this.
So, I introduced a settings dialog. Which will be helpful later on for other preferences such as reading theme. This dialog is hidden from screen readers but available to keyboard users.
In the introduction section, I used a few idioms to express some thoughts. Being idioms, I marked it up with an
i element. But to my surprise, NVDA wouldn't convey the opening and closing of the accordion. Because of certain styles such as italic.
I realised long after some troubleshooting. I wish to cry but knowing that I figured the reason, I stayed indifferent. And left the idioms unmarked.
Here are resources that helped along the way. Big thanks to the authors.
How A Screen Reader User Surfs the Web. A workshop by Leonie Watson for Smashing Magazine. Published on Youtube
Creating an Accessible Modal by Ire Aderinokun
That's it for this milestone!
However, I'll be sharing my progress on Twitter @toheebdotcom. Join the discussion below.
I still have more clickbaits to resolve though. One at a time.
Till next time, Ò dabó!