DEV Community

Cover image for An Introduction to ARIA States

An Introduction to ARIA States

lkopacz profile image Lindsey Kopacz Originally published at ・5 min read

Originally posted on If you'd like to see video examples of how screen readers interpret these, they are at the source!

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: "Section 1, Collapsed, Button." Then when you use the screen reader commands to open it, it will read: "Section 1, Expanded, Button." (If you'd like to see the video sample of this, check out the original blog post.)

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.

If you don't add in the aria-expanded attribute, when I press the open up the menu, it doesn't stop reading "Section 1, button" tell me if the accordion is open. The interruption is helpful to understand the space. (If you'd like to see the video sample of this, check out the original blog post.)

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, while hidden 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 class="u-hiddenVisually hidden-new-items-text">
    New Tweets available.

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:

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!


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.

Let me know on Twitter what you think! Also, I now have a patreon! If you like my work, consider becoming a patron. You’ll be able to vote on future blog posts if you make a \$5 pledge or higher! Cheers! Have a great week!

Discussion (5)

Editor guide
paulooi profile image
Paul O

i really enjoyed this post. I'm also learning about a11y more on the job and trying to advocate for it in our office.

since you mentioned aria-hidden i have a question then. one situation we came across is with pagination. if the "next page" link (usually an arrow icon) has the same url as the "page#"link next to it, wave throws an accessibility error that there's a redundant link adjacent to one another. it won't happen on every page mind you but suppose your collection of page links is: page 1, page 2, next page. and you're currently on page 1. I'm sure I'm not the only Dev to have encountered this but haven't come across any good solutions online. would aria-hidden work here on the arrow or page 2?

elliot profile image
Elliot • Edited

This is my first time hearing the idea of styling by using ARIA attributes in the CSS. Forces you to be on top of accessibility, forcing you to even think about it when styling.

Nice article :) I'm interested in reading more in this series.

lkopacz profile image
Lindsey Kopacz Author

I actually got the idea from! They had a very good point!

However, it is my personal preference using classes for styling and not attributes.

One of the wins of using ARIA attributes to style interactive components like this is that the component will never work without the ARIA changes baked in. This may not matter in very small teams or teams where there is across-the-board knowledge about accessibility, but for all other cases, I would highly recommend using the ARIA attributes in the CSS, too.

This was a great post, btw!

anpos231 profile image

I think your posts increased IQ of everyone how reads them by at least 10 points :P

Thank you for making the community more aware of a11y.

adam_cyclones profile image
Adam Crockett

Enduring CSS advocates this wonderful practice of using aria as a statefull styling mechanic. I'm also banging on a bout it. Good work!