Easy web accessibility wins: Hashtags

Steve Frenzel - February 16, 2024

Back to blog
Background: Light pink color. Foreground: Many # symbols and in between are the words 'Easy web accessibility wins: Hashtags'.

There are many opportunities for simple web accessibility wins. Not only developers and designers should have a duty to create an accessible product, but also content creators.

One of these small wins can be achieved by tweaking your hashtags. This process in general is called “shifting left”, you can learn more about it here: What Happens When A Project Team Shifts Accessibility Left?

Table of contents

The problem

Let’s turn the title of this article into a hashtag: #easywebaccessibilitywinshashtags

Not only was the fear of making a typo my constant companion while writing, it’s also super hard to read. Fortunately, there is a writing method that could help: Pascal case!

If we apply it to our example, the text is already much easier to read visually: #EasyWebAccessibilityWinsHashtags

So we’ve removed a barrier for sighted people, but what about those who rely on screen readers, for example?

The data

Since 2008, WebAIM has been conducting a screen reader user survey, which shows, among other things, which software is popular and how important the correct use of heading elements is, for example.

Based on this survey, I have selected the four most popular screen readers in order to test whether I can find a solution for consistently announcing hashtags correctly.

For this purpose, I have created a test website to carry out these tests. This code is NOT production ready and is for demonstration purposes only. In the last section I explain my thought process regarding this example website. There are five test cases, for each I document the results in a table.

  • ”No” means that the words were not pronounced individually
  • ”Yes” means that the individual words were pronounced correctly
  • ”Partially” means that the individual words were pronounced more or less correctly
  • ”Not tested” means that a test was not possible

Test case 1: All lower case

A <div> with an WAI-ARIA role of “note”, containing the all lower case string “#easywebaccessibilitywinshashtags”.

Google ChromeMozilla FirefoxApple SafariMicrosoft Edge
JAWSPartiallyPartiallyNot testedPartially
NVDAPartiallyPartiallyNot testedYes
VoiceOverNoNoNoNo
NarratorPartiallyPartiallyNot testedPartially

Test case 2: Pascal case with a <div> element

A <div> with an WAI-ARIA role of “note”, containing the Pascal case string “#EasyWebAccessibilityWinsHashtags”.

Google ChromeMozilla FirefoxApple SafariMicrosoft Edge
JAWSYesYesNot testedYes
NVDAYesYesNot testedYes
VoiceOverNoNoNoNo
NarratorYesYesNot testedYes

Test case 3: Pascal case with a <p> element

A <p> element, containing the Pascal case string “#EasyWebAccessibilityWinsHashtags”.

Google ChromeMozilla FirefoxApple SafariMicrosoft Edge
JAWSYesYesNot testedYes
NVDAYesYesNot testedYes
VoiceOverNoNoNoNo
NarratorYesYesNot testedYes

Test case 4: Manually added aria-label

A <div> with an WAI-ARIA role of “note” and an aria-label containing the string “#EasyWebAccessibilityWinsHashtags”. Inside is the actual element, which is another <div> with the aria-hidden='true' attribute.

Google ChromeMozilla FirefoxApple SafariMicrosoft Edge
JAWSNoYesNot testedNo
NVDANoNoNot testedNo
VoiceOverYesYesYesYes
NarratorNoNoNot testedNo

Test case 5: Automatically added aria-label via JavaScript

A <div> element with a WAI-ARIA role of “note”. Inside is the actual element, which is another <div> with the aria-hidden=‘true’ attribute. The content is injected via JavaScript, adding an aria-label to the parent <div>. This string has no ”#” symbol and added white space between every word.

Google ChromeMozilla FirefoxApple SafariMicrosoft Edge
JAWSNoYesNot testedNo
NVDANoNoNot testedNo
VoiceOverYesYesYesYes
NarratorNoNoNot testedNo

The results

For me, the results of the first three test cases are not as surprising as the fact that the same screen reader on the same website can sometimes behave completely differently! 😱

The last two test cases are particularly interesting, as VoiceOver and JAWS worked with my solution, but the other screen readers did not.

It also showed that JAWS is (for now) the leading software for a reason, as it works particularly reliably in combination with Firefox. VoiceOver is the worst performer for me, as it has problems where the others at least partially announce the hashtag correctly.

The Conclusion

In an ideal world, no hacks would be necessary for a hashtag to be announced correctly. Unfortunately, the reality is different and based on my tests, my conclusion is to choose the lesser of two evils as it was rendered correctly by the majority of the software tested.

In other words, using Pascal case when writing hashtags can make a significant difference and helps to shift left. Therefore, the responsibility for accessibility would lie with the content creators and not with the designers or developers. For better or for worse…

Another problem

When creating the test website, I quickly had to ask myself the question: What kind of HTML element would a hashtag actually be? If they were displayed collectively, I would turn them into a list element within a list. But solo, for example in the middle of a sentence?

After a little research, my conclusion was that there is no native element that fits exactly, so I would assign the WAI-ARIA role note, as it makes the most sense to me:

A note role suggests a section whose content is parenthetic or ancillary to the main content. - mdn web docs

The reason for this is a warning from my axe-linter extension, which came up when I tried to assign aria-label to a <div>, <span> and <p> element:

Ensures ARIA attributes are not prohibited for an element’s role - Deque University

My goal was to be able to work as consistently as possible with a specific role, for a better comparison. But is a hashtag really a section, like it says in the definition?

In my solution, I wrapped it in a <div> and added an aria-label to avoid announcing the content twice in VoiceOver. Shortly afterwards I read this article by Adrian Roselli on the subject of “aria-label”

Please stop adding aria-label to <span> and <div>. They won’t love you back no matter what you name them. - Mastodon

In addition, he also tested the WAI-ARIA role note with different screen reader and browser combinations: Results of Adrian’s test

After going back and forth, I still decided to stick to this role for my example, as I’m making it very clear that the example code is NOT production ready.

However, I encourage you to do your own research and test for yourself. Also please let me know if there’s a better solution, cause I’m no expert and always open to suggestions! 🙏