Aria Labels here we come
Tags: a11y, html
Published: 2021-04-06 16:41:01

I recently built an e-commerce site, and I attempted to build a strong accessible foundation along the way. The project is mostly complete, but I thought it was a great opportunity to comb through the project to add aria labels where they are needed.

I hope this can serve as an introduction to adding aria labels in a React/NextJS project.

## Landing Page

![landing-page-one](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qi2vuf59y2ugsoydsqrq.gif)

On the landing page we have a few items to address. Using Firefox's Accessibility Inspector we can see multiple issues in the header alone. 

![Screen Shot 2021-04-06 at 11.35.58 AM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1oyjylfntu54o38lmryg.png)

### Burger Menu 

First and foremost I want to make sure the burger menu is accessible and makes sense to everyone. Adding an aria-label easily removes our warning.

```
<button 
  className={ menuOpen ? "burger-btn active" : "burger-btn"}
  onClick={handleMenuToggle}
  aria-label="open main menu"
>
```

But, you may notice that this button is a toggle button, so what happens when our menu is open? 

![Screen Shot 2021-04-06 at 11.42.25 AM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wx81k4rw9iadloahpqwm.png) 
 
Our label informs our user that this button will "open main menu". But the menu is already open, and visually we are showing a huge X, so this is rubbish. 

Using the same ternary logic I used for my button className, I can update the aria-label to change based on the state. 

```
<button 
  className={ menuOpen ? "burger-btn active" : "burger-btn"}
  onClick={handleMenuToggle}
  aria-label={ menuOpen ? "close main menu" : "open main menu"}
>
```

Now our aria label updates with our menu opening and closing. When I use voice-over I hear "open main menu, button" when I apply focus (tab to the button) and when I hit enter, I hear "close main menu" immediately. That worked better than I even though honestly.

### Page Header

My site title is "C&G", which doubles as a link to the landing page, though I am not sure you'd never know that from the voice over. What I currently hear is "link, C & G". I'm going to add an aria label to this as well.

```
<Link href="/">
  <a aria-label="c & g home page">C<span>&</span>G</a>
</Link>
```

Now I hear "link, c & g home page" when I apply focus to the element. If this link element looks strange, just know I'm using NextJS along with React.

### Cart Icon

Next up is our cart icon. The code currently reads as such

```
<button 
  className="header-cart"
  onClick={handleCartPreviewClick}
>
  <img className="cart-vector" src="/shopping-cart-vector.png"></img>

  {context.contextCart.length > 0 ? 
  <span className="cart-count"> {context.contextCart.length}</span>
  : null }
</button>
```

I immediately notice some issues. For one, my image tag has no alt attribute. While I'm fixing that, I can add a ternary aria label just like our burger menu button. 

```
<button 
  className="header-cart"
  onClick={handleCartPreviewClick}
  aria-label={ cartPreview ? "close shopping cart preview" : "open shopping cart preview" }
>
  <img 
    className="cart-vector" 
    src="/shopping-cart-vector.png"
    alt="shopping cart" 
   />
{context.contextCart.length > 0 ? 
    <span className="cart-count">{context.contextCart.length}</span>
: null }
</button>
```
That solves the same issues I had with my burger menu toggle button. Although when I use the screen reader I only receive information about the image inside the button, or the span when I am first loading the page. I'm not thrilled about that, I'd like to have the number of cart items be relayed somehow. I am going to try to add that into the button's aria label. 

I attempted to interpolate my cart items length into the aria label, but that doesn't work. So I will leave that issue open for now. At least the button instructions make sense now.

## Conclusion

Well addressing only the header took a while, so I will have to write another article detailing the slider on the landing page and digging further into our cart items - which I fear aren't laid out too well.

If you'd like to see the page as it stands currently or checkout out the code the links are included below.

[live page](https://candg.netlify.app/)
[github repo](https://github.com/JDHofmann/plugs-frontend)