DEV Community

Create an accessible dropdown navigation

Lindsey Kopacz on December 05, 2018

Hover navigations are pretty simple to do without JavaScript, which is how I usually see them implemented. The HTML and CSS are pretty simple. ...
Collapse
 
equinusocio profile image
Mattia Astorino

Nice! Just note that keyboard navigation is not the only thing to consider for accessibility. You should also consider to add aria attributes and implement aria widgets.

You may find useful this resource:
w3.org/TR/wai-aria-practices-1.2/

Collapse
 
lkopacz profile image
Lindsey Kopacz

totally! I actually presented about aria stuff a while back and I feel like it would be a good extension of this blog post!

Collapse
 
lkopacz profile image
Lindsey Kopacz

Additionally, I tend to use aria as a fallback since HTML5 is so great now <3

Collapse
 
equinusocio profile image
Mattia Astorino • Edited

Aria attributes are mandatory to support screen readers. Using semantic tags is not enough ☺️

EDIT
Since people doesn't read but go for interpretation i will explain and translate my really simple statement:
If you need to provide extra informations to SR, your are obliged (so why they are mandatory) to use aria attributes. No one will save you.

Thread Thread
 
lkopacz profile image
Lindsey Kopacz

After talking with blind users (IE the ones who use screenreaders most), they tell me they prefer HTML5 and add ARIA in afterward if more context is needed.

Sometimes manual testing I learn that it's not always mandatory, but if someone is visually impaired is telling me it's not mandatory, I am going to listen to them.

A lot of times ARIA isn't mandatory, it just adds in extra context when things aren't super clear. HTML5 is built to be accessible out of the box, it's when we create advanced features is when we need ARIA.

Thread Thread
 
equinusocio profile image
Mattia Astorino • Edited

Wait :). They aren’t mandatory when you don’t need to provide more informations. But if use for example a nav element as tab widget you must tell to SR which element is selected. And you can do that through aria-states and roles. These are design patterns defined inside the WCAG guidelines and we must follow them to be WCAG AA(A) compliant.

Another example is when you have an interactive element without content (and this is not an advanced feature), you need to provide the aria-label attribute to describe the action to SR.

In a multilevel menu (pure semantic html) you must tell elements relationship to SR otherwise users won’t know where they are... even in this case you should use aria attributes and roles to avoid the UI pollution.

Btw good job with this article. πŸ‘πŸ»

Thread Thread
 
rachlivero profile image
Rachel Olivero

I think any blanket statement that ARIA attributes are required is dangerous. For example, saying that ARIA is required on a form field where a element is already correctly implemented is at best redundant work for the developer, and possibly results in extraneous verbosity for the screen reader user. (Trust me, as a screen reader user, I don't want more speech than I need when I'm trying to work efficiently.) While there is definitely a place for ARIA, and a site-wide nav menu that implements full arrow-key navigation would definitely benefit from this enhancement, ARIA is not required in all situations.

Thread Thread
 
equinusocio profile image
Mattia Astorino • Edited

I just said that aria attributes are mandatory because you can't provide informations to SR (when obviously there is the correct situation) in other ways. You MUST use them to provide additional and useful informations, you can't avoid to use them in such situations.

Thread Thread
 
lkopacz profile image
Lindsey Kopacz

I think you should listen to the person who uses a screenreader daily.....

Thread Thread
 
equinusocio profile image
Mattia Astorino

I do. Please don't be arrogant because you don't know how i work and what i do daily. I'm just telling that there are official specs, guidelines, certifications that we must follow.

To close this ridiculous aggresion, i say again nice article. Bye.

Thread Thread
 
lkopacz profile image
Lindsey Kopacz

I talked to her and she told me where I could improve with ARIA. She asserted that from her experience as a daily screen reader user that saying they are mandatory is a bit dangerous. That's not saying any of us disagree with your assertion. I also find you're being kinda aggressive by stating that us explaining our experience is aggressive.

Not sure how me asking you to listen to her is arrogant on my part. But bye, I guess?

Thread Thread
 
equinusocio profile image
Mattia Astorino • Edited

It’s arrogant and aggressive saying that i should β€œtalk” to who use screen readers for real.. supposing that I’m not already doing it and it wasn’t a question. I never said we must use aria-attributes everywhere. Peace and love.

Thread Thread
 
theworstdev profile image
Kurt Kemple

"Aria attributes are mandatory to support screen readers. Using semantic tags is not enough" sounds like you're saying we have to use aria attributes everywhere. It's pretty arrogant to make such blanket statements.

Thread Thread
 
maxwell_dev profile image
Max Antonucci

Recommending you listen to people who regularly use screen readers, and likely have more knowledge and experience to add to ours, isn't arrogant or aggressive. It's a reasonable suggestion and a way to be more empathetic as a developer. Calling that "ridiculous" seems more ridiculous to me.

Thread Thread
 
equinusocio profile image
Mattia Astorino • Edited

No Kurtis Kemple. Sounds like if you need to provide useful informations to SR you need (are mandatory) aria widgets, states and attributes because there aren’t other ways to do that. It’s so hard to understand? I think they just misunderstood my words without asking what i was meaning.

Thread Thread
 
ben profile image
Ben Halpern

Hey can we all cool it here folks?

As an outsider to this conversation I definitely feel like people are talking past each other.

Thanks a lot.

Thread Thread
 
equinusocio profile image
Mattia Astorino • Edited

Yeah. Sorry, it was my fault because i was not so clear with my previous messages (πŸ€”).

Collapse
 
link2twenty profile image
Andrew Bone

Do you know about focus-within?

You could do something like this and still have full keyboard navigation

.menu__item:hover .submenu,
.menu__item:focus-within .submenu {
  padding: 0.5rem 0;
  width: 9rem;
  height: auto;
  background: #eedbff;
  clip: auto;
}

Tweeked example on jsfiddle

Oh, and good to see you got the syntax highlighting working πŸ™‚

Collapse
 
lkopacz profile image
Lindsey Kopacz

Hmm interesting. I'll check it out. What's the support like?

Collapse
 
lkopacz profile image
Lindsey Kopacz

Ugh yeah, the reason I haven't used this is because most of my clients still support IE and Edge. Me: sobs in a corner.

Thanks for showing me this though. Pretty cool to learn about how people are using pseudo-classes.

Thread Thread
 
link2twenty profile image
Andrew Bone

I'd probably still use the CSS method, I try to avoid JS where I can, if I could and have your method as a backup in case focus-within wasn't supported.

try {
  document.querySelector(':focus-within');
} catch (err) {
  console.log("focus-within is not available, using polyfill");
  focusWithinFallback(topLevelLinks);
}

function focusWithinFallback(array) {
  array.forEach(link => {
    ...
  }
}
.menu__item:hover .submenu,
.menu__item:focus-within .submenu,
.menu__item.focus .submenu {
  padding: 0.5rem 0;
  width: 9rem;
  height: auto;
  background: #eedbff;
  clip: auto;
}

This would give you support back to IE6 πŸ˜€
Unparsable CSS is ignored by default.

Thread Thread
 
lkopacz profile image
Lindsey Kopacz

I'm a front-end dev, I am aware that unparsable CSS is ignored by default ;)

Thread Thread
 
link2twenty profile image
Andrew Bone

It was more for people that might read later 😜

Thread Thread
 
lkopacz profile image
Lindsey Kopacz

Yeah, I definitely understand the avoiding JS by default mindset. For me, I usually think this way too. My rule of thumb is always to use JS to toggle classes and use CSS to change the styling vs control the styling in JS. Over the years though, I've been less resistant to use JS depending on circumstance so long as I'm writing it in a minimalistic style.

I'll play around more with :focus-within for my follow up post :).

Collapse
 
moopet profile image
Ben Sinclair

I tried this (which is admittedly a bit messy) using relatedTarget on the event to determine whether the link was headed to another menu- or submenu-item. I'm also clearing all the top level focus classes whenever the top level menu is re-focused... it seems to work.

topLevelLinks.forEach(link => {
    if (link.nextElementSibling) {
      link.addEventListener('focus', function() {
        topLevelLinks.forEach(link => {
          link.parentElement.classList.remove('focus');
        });

        link.addEventListener('blur', function(e) {
          link.parentElement.classList.remove('focus');
        });

        this.parentElement.classList.add('focus');
      });

      const subMenu = link.nextElementSibling;
      const subMenuLinks = subMenu.querySelectorAll('a');

      subMenuLinks.forEach(link => {
        const topLevelLink = link.parentElement.parentElement.parentElement;

        link.addEventListener('focus', function() {
          topLevelLink.classList.add('focus');
        });

        link.addEventListener('blur', function(e) {
          if (e.relatedTarget) {
            const targetTopLevelLink = e.relatedTarget.parentElement.parentElement.parentElement;

            if (targetTopLevelLink != topLevelLink) {
              topLevelLink.classList.remove('focus');
            }
          }
        });
      });
    }
  });
Collapse
 
nlynchbs profile image
Nicole

Hi, this is great. I found your follow up CSS-only solution using :focus-within. But wondered if you posted the follow up JS solution for traversing backwards through the menu?

Collapse
 
lkopacz profile image
Lindsey Kopacz

I haven't gotten to it yet, maybe my next blog post πŸ€”