An Introduction to ARIA States
Note: this blog is an archive and not actively maintained. Some information may be out of date. If you'd like to see what I am working on or work with me in a consulting capacity, visit my website lindseykopacz.com.
Hey friends! Today’s blog post comes to you from my Patreon folks’ poll. It’s a follow up from one of my previous posts about Demystifying ARIA. ARIA can be utterly mysterious and daunting, but it’s handy. One of my favorite ways to use it is to communicate state to screen readers.
I’m seeing a positive trend in the a11y community. Instead of using classes to style elements, a11y folks are styling by using ARIA attributes in the CSS. This helps enforce accessibility standards and prevent people from cheating accessibility. The attributes I’ll be going over today are aria-expanded
, hidden
, aria-hidden
, and aria-current
.
The aria-expanded
attribute
aria-expanded
is one of the few aria attributes that does not have an HTML5 equivalent. Please tweet me if I am wrong, but at the time of writing, I believe this to be correct. In the Accessible Accordion post, I used aria-expanded
to convey the section’s state.
Why is this helpful? Let’s take the accordion example that I went through in the blog post that I linked in the previous paragraph:
Note: I changed the code in the above sample to have the CSS tied more to the attributes and less to CSS classes.
If you go through this on a screen reader, you’ll get something like this:
Imagine if we took off the aria-expanded
attribute which I did in a separate CodePen.
Note: I kept most of the original code in here. That way, I could demonstrate the visual opening and closing. Additionally, it shows how it doesn’t work for a screen reader user.
Do you notice how when I open the button, it doesn’t communicate whether the section is open or closed? This is critical for a screen reader user to know what is going on. Withholding verbal communication of state is confusing for screen reader users.
Anytime we hide content that expands upon user action, use aria-expanded
. When you use JavaScript to toggle it, it becomes a better user experience.
The hidden
attribute
If you saw my notes above, you may have seen that I changed up the code. Previously, I had the accordion using an aria-hidden
attribute (more on that later). Upon the button click, I would toggle the value to be true
or false
. The reason for that is because hidden
is the HTML equivalent of display: none
.
When I started with accessibility, the motivation to hide content from screen readers baffled me. Why would I want to exclude them from content?? I used to be resistant to ever using hidden
, but the reality is sometimes it’s necessary. With some forms of content, we don’t want to expose content to a user until we interact with it. For example, with modals and accordions, we only want to see what’s inside if they are open.
When to use aria-hidden
There’s one significant difference between aria-hidden
and hidden
:
aria-hidden
only hides elements from screen readers, whilehidden
hides from everyone.
I ask myself if there are HTML elements that are primarily for decoration. If so, I might want to use aria-hidden
to hide it from screen readers but not from visually-abled users.
One of my favorite reason’s to use aria-hidden
is to prevent repetition. This, for example, is the Home button for Twitter:
<a class="js-nav js-tooltip js-dynamic-tooltip">
<span class="Icon Icon--home Icon--large"></span>
<span class="Icon Icon--homeFilled Icon--large u-textUserColor"></span>
<span class="text" aria-hidden="true">Home</span>
<span class="u-hiddenVisually a11y-inactive-page-text">Home</span>
<span class="u-hiddenVisually a11y-active-page-text">
Home, current page.
</span>
<span class="u-hiddenVisually hidden-new-items-text">
New Tweets available.
</span>
</a>
In this instance, the screen reader announces one of the “a11y page texts” based on the context of the page. I want you to take note of this line of code:
<span class="text" aria-hidden="true">Home</span>
This is the one that is actually on the screen. We have the dynamic options for the screen reader like “Home,” “Home, current page,” and “Load new Tweets.” We don’t need that context on the Home button if we can see the visual cues.
With that being said, my rule is if we are toggling states, I use hidden
. If there’s duplicate or unnecessary content, I’ll use aria-hidden
.
The aria-current
attribute
Fun fact, this one is totally new to me. I didn’t learn about this until I saw Eric Bailey’s tweet about the a11y project redesign:
A little detail I'm proud of for the upcoming @A11YProject redesign is using `[aria-current]` as a styling hook for our table of contents component. Instead of using a ".is-current" class or the like, we're typing visual appearance to semantic state for where you are on the page. pic.twitter.com/tt3k3MYEuk
— Eric Bailey (@ericwbailey) June 1, 2019
The best part about the web and accessibility practices is I learn something new every day. After seeing this tweet, I found Léonie’s post on aria-current. Something they pointed out is that we predominately use CSS to show the “current” element visually. In my Drupal days, most themes had an .is-active
class if you were on a menu item that reflected the current URL.
As Léonie said, the problem with this approach is CSS is mostly visual. Meaning (with an exception) 0 of the styling is exposed to screen readers. Using aria-current helps ensure that we communicate the context to screen reader users. According to WAI-ARIA 1.1, there are a few values that aria-current
could take on:
- page for a link within a set of pagination links, the current page as represented in the navigation, etc.
- step for a step-based process.
- date for a current date.
- time for a current time.
Additionally, this should be only one element in a set of elements can have an aria-current
value. Otherwise, it will confuse the screen reader!
Conclusion
I plan to have more blog posts about ARIA and state in the future. I hope this helped you demystify a few more aria attributes.
Cheers! Have a great week!
About Lindsey
Lindsey is an accessibility expert, JavaScript lover, and Front End Developer who's passionate about inclusivity both inside and outside the web. Read more about her on the About Page