I’m a recent addict of Habitica, the good-habit-building game that turns your life into an RPG, and I was thrilled when I realized their stack was basically what I knew best (well I thought I knew it well but then oh geez). I took a look for low hanging fruit in their current feature requests, and noticed some comments about screen readers being unable to use the site.
The person I was talking to was using JAWS on Windows, and I don’t have either of those things, but some random googling got me to this great writeup on how to label stuff. I later found Google’s Web Accessibility course which clarified a few things. One thing that kinda baked my noodle: people who can’t see your site see the DOM. That’s what they interact with.
I didn’t really have the rights or the knowledge to mess with Habitica’s DOM structure, but I could for sure add
aria-label attributes where appropriate. I started taking apart various views.
Oh first I messed around with Apple’s Screen Reader! It was a little hard to figure out at first, and incredibly annoying when it was trying to narrate what I was doing clicking between seven different windows. But eventually I was able to get it to say ‘button’ about all the 100 buttons on the Habitica inventory screen. Sure enough, that was unusable for the blind.
I started by adding in Labels wherever they were needed. Normally
aria-labels are required when you have something like an icon button: something where the sighted will see what a thing is and know right away what it does. In the case of the Habitica inventory, the problem was that the explanatory text was in a popover that no screen-reader would ever activate or read. That meant hundreds of labels needed to be added.
Worse, each kind of icon (equipment, pets, collectibles) were all being instantiated in the view with seperate, similar loops. I had to insert
aria-label tags in seven or eight places just in the first view! It was taking time and I didn’t know the Jade Syntax well so I kept messing up.
Eventually I got a page done (one of five) and headed to bed pretty satisfied. Then as I was lying in bed I realized that there was a much better way to do all this.
I’m inordinately proud of this little script. It operates off the knowledge that the text we want to apply as an
aria-label is in a
popover-title attribute already. It grabs that text and adds a label to every button that had a popover.
So I was really happy! All I needed to do was run this JQuery code on every affected page and they would work, yay!
I found myself pretty stymied, though, by figuring out where to put this code… A… service? One of the routes? A controller somewhere?
This script overwrites any existing aria-label attributes, I didn’t want it running on every page, so adding it to the footer was wrong.
I ended up include it in the target pages’ views and plunking a .js file down in that folder, which is in “/views/” so I know that’s not ideal, but I think I need to study Angular patterns a bit more if I intend to do anything that’s as reliable and simple as my kind of hacky answer.