Devographics / StateOfJS-2020

Other
103 stars 20 forks source link

Inaccessible hamburger control #40

Open aardrian opened 3 years ago

aardrian commented 3 years ago

I am limiting accessibility feedback to the hamburger navigation, though the site is full of accessibility issues and barriers (you can test with just your Tab key to start). The hamburger, however, is a critical failure that blocks the greatest set of users from accessing any of the content on the site while also demonstrating a broad swath of WCAG failures coupled with a technically straightforward fix.

The control that shows and hides the navigation when zoomed or in a mobile browser is inaccessible.

  1. It has no accessible name,
  2. It has no focus styles and the browser default is removed,
  3. The hover style for the hamburger (the close button has no hover style) cannot be used as the focus style since it has a 2.2:1 contrast ratio with the adjacent border,
  4. It does not programmatically indicate its expanded/collapsed state,
  5. The primary navigation is not hidden, forcing 23 Tab presses or mobile swipes to get to the hamburger,
  6. The button to close the navigation, and all the navigation, precedes the hamburger control in the DOM, forcing a user to know to tab backward,
  7. The button to close the navigation has an accessible name of "[en-US] general.close_nav" (from the nested <span>),
  8. The SVG in both buttons lacks an image alternative, or should be hidden completely from screen readers if no alternative is appropriate (the latter applies in this case),

The relevant code today:

<button class="Pagination__SidebarToggle-fmwu6l-2 dKQIoy SidebarToggle">
  <svg […] class="Hamburger__Container-j038hg-0 fIONJq">
    […]
  </svg>
</button>
.dKQIoy:focus {
    outline: 0px;
}

The easiest way to address this:

Your HTML and CSS then might look like this:

<button class="Pagination__SidebarToggle-fmwu6l-2 dKQIoy SidebarToggle" aria-expanded="true|false" aria-label="Navigation">
  <svg […] class="Hamburger__Container-j038hg-0 fIONJq" aria-hidden="true">
    […]
  </svg>
</button>
<div class="Nav__NavContainer-uo6ep0-1 iskZBJ">
  […]
</div>
.dKQIoy:focus svg {
    stroke: rgb(34, 36, 41);
}
.dKQIoy:focus {
    background: rgb(65, 199, 199);
}

For more details on disclosure widgets, including how they work, how to code them, how they are exposed in screen readers, and so on, I have a tutorial: Disclosure Widgets.

I recommend you use this pattern for the language selectors as well, since right now they are completely inaccessible because they use <div>s with click handlers instead of native <button> elements.

SachaG commented 3 years ago

Thanks for the detailed feedback! I'll definitely address this.