We know it's important to add content descriptions, but what happens when you don't? In this post, we look at a TalkBack feature designed to help users provide their own labels, how it can start to get a little messy and what you can do to help them.
Let's pretend I wrote an app, Super Cool, for my social network. It currently only shows a single post with some gibberish, but it has like and dislike buttons for every post.
Unfortunately, I forgot to add content descriptions to the buttons. This means that if a TalkBack user is interacting with Super Cool, and they focus on either of these buttons, they'll hear "Button, Unlabelled".
The user will be frustrated, but is probably used to it - many apps are missing content descriptions. After a while however, they learn that the first button after the text post is Like so they decide to add a custom label. This will mean that they don't have to remember it anymore!
Alas, I am a lazy developer: I used the
android:onClick attribute in XML to bind to public methods in my Activity rather than creating a View ID and associating an OnClickListener with it.
<ImageView android:onClick="onClickUpvote" android:src="@drawable/up" ... /> <ImageView android:onClick="onClickDownvote" android:src="@drawable/down" ... />
What I didn't know was that using custom labels requires elements to have IDs, preventing users from even making the interface more helpful for themselves.
Months down the line, I refactor the app and decide not to use the
android:onClick attribute and to add an ID to each of my buttons:
<ImageView android:id="@+id/like_image" android:src="@drawable/up" ... /> <ImageView android:id="@+id/dislike_image" android:src="@drawable/down" ... />
"Awesome," says the new user (the old user has long since uninstalled my app). "I can finally add some custom labels!"
Now, at last, the buttons will have user-added content descriptions, "like" and "dislike", and these will be read aloud when TalkBack focuses on these elements.
The user is now somewhat content. As a developer though, I continue to refactor the app. I notice that I added IDs named for "like" and "dislike" even though my domain language is "upvote" and "downvote". I decide to change it.
Suddenly, that content user is once again missing TalkBack descriptions for these two buttons.
The reason is that custom labels rely on the IDs remaining stable. If they change, then the labels are orphaned. Even worse, if the IDs are exchanged between Views, then the labels will be applied to the incorrect Views.
At long last, I decide to be a good, considerate developer and add a content description to Super Cool’s buttons explicitly:
<ImageView android:id="@+id/upvote_image" android:contentDescription="upvote" android:src="@drawable/up" ... />
The user’s custom labels will be ignored, and our content description will be used instead.
In conclusion, it really is important to add content descriptions for actionable elements in your UI. Not only does it provide a better experience for your users from the start, but it also saves them a potentially long and frustrating journey.