DEV Community

Discussion on: Accessible Modal With Or Without JavaScript

Collapse
 
grahamthedev profile image
GrahamTheDev • Edited

Sadly this is not accessible for screen reader users and there are a few things you need to do.

Firstly screen reader users navigate with shortcuts for headings 1-6, sections, links on the page, buttons etc. They can jump out of your modal with any of these shortcuts.

In order to stop this (and it is quite difficult) you need to first add aria-hidden="true" to anything outside your modal. That bit is easy enough, especially if you structure your document correctly.

Where it gets difficult is that anything that is focusable outside your modal needs either disabled adding to it (if appropriate) or tabindex="-1".

Also when you enable JavaScript interception of the link you change it into a <button> effectively, so you should add aria-role="button" to it to indicate that this will not result in navigation.

At the same time you should add aria-haspopup="dialog". aria-labelledby="dialogTitle" and still use `role="dialog" on the dialog itself.

Also use semantic HTML (the <dialog> element is a great place to start if creating a dialog as in some browsers you get focus trapping built in) and yet again role="button" on your close links (or better yet, use JavaScript to change them out for actual buttons as I think about it).

There are probably other things I haven't thought about from a quick glance through but that should give you a good start on things to fix.

Oh and this may soon get really easy if inert ever gets implemented properly in browsers (a lot of browsers have partially implemented it behind a flag but as of yet 0 default browser support)

Collapse
 
maxart2501 profile image
Massimo Artizzu

Great answer and TIL about the inert property.

Collapse
 
madsstoumann profile image
Mads Stoumann • Edited

Thanks for your comprehensive review!

My whole point is not looking at it as a modal for screen-readers, but as content you navigate to and from, using the fragment identifier # (and bits of JS to focus on the previous id, when you change the fragment identifier to just #).

I assume inline links (yourdomain.com/#about) works just as well on screen-readers?

For people without screen-readers it will function as a modal, with focus-trapping etc., but for screen-readers as content you navigate to and from.

PS! I just tried "Narrator" in Windows, and it correctly jumped to the modal and back when I “closed” it.

Collapse
 
grahamthedev profile image
GrahamTheDev

The link part would work fine, the problem comes with understanding content. A hyperlink saying "close" is not very useful to a screen reader user without knowing they are in a modal for example (could possibly be fixed with an aria-label explaining but still not sure if that is ideal).

Also in a sandbox it is fine but in the real world a modal would be used to alert information etc. So at places where you are likely to use it it would be expected to have a button anyway (such as in a form)? (Maybe there is a use case but I can't think of it at the moment)

The other issue is when JavaScript is turned off if you open the second "modal" and then close it you are returned to the top of the page, could possibly be fixed by giving the link that opens it an ID and making the close buttons point at that instead though?

One thing that would improve it is moving the id to the heading of the "modal" but that would make the selector hard work for :target.

As a concept I do think it is good, but the problem is expected behaviour.

The use case I can think of is for cookies consent if you had the "modal" open on page load.

I will think about it more as I think you have a concept that probably has some good use cases but until I think of the use cases I cannot recommend best actions to fix things (if you have some use cases in mind that would be great).

Thread Thread
 
madsstoumann profile image
Mads Stoumann

Again, thank you for your comprehensive answer!

To recap:

  1. The :target-based modal works just fine for non-screen-readers using only CSS and HTML.
  2. With JS enabled, it works fine for people like me, who cannot use a mouse.
  3. But for screen-readers, with inline links, the behaviour can be unexpected.

I need to know how screen-readers normally announce inline links, using fragment identifiers - I'll look into that.

Because, could it potentially be enough to set aria-hidden="true" on the modal by default, and change this to false on the hashchange-event?
And set the aria-label to "Back to previous loccation"?