Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can restrict the tab key press only within the modal popup when its open?

I have a modal popup opened. I have accessibility requirement. So added ARIA related labels. But when i click tab key continuously focus going to the page behind the actual page.

Added role="dialog" in html file

But when modal opened i want only the focus navigate within the modal popup.

Working on Angular4, HTML5 project. Better if we find a solution within HTML file itself. I mean without added any javascript/jQuery related stuffs to prevent this

like image 845
Rajaa Avatar asked May 04 '18 15:05

Rajaa


People also ask

How do I open modal pop up in new tab?

User can open modal in same tab by clicking left mouse button on item. User can also click middle mouse button (scrollbar) to open modal in new tab.

How do I disable background when pop modal is open?

The key idea is to have pointer-events: none; for the body when modal is open. But the specific elements you want to be interacted with should have e.g. pointer-events: auto; . In the example you can click both buttons when dialog is hidden, but only Toggle Dialog button when dialog is shown.

How do I make my modal keyboard accessible?

Tab through your page to make sure modals are keyboard navigable. You want to make sure that as you tab through your page, focus doesn't jump outside the modal window to the main page where it will be hidden. When the modal is open, try tapping the ESC key to make sure it closes the modal.


3 Answers

You are asking about focus trap, it's nicely demonstrated in this demo: https://focus-trap.github.io/focus-trap/

Adding role="dialog" will not automatically provide trap the focus within that element. In fact, there's no native focus trap provided by browsers.

You need to go with one of following options:

  • implement focus trap by yourself (good article on this: https://hiddedevries.nl/en/blog/2017-01-29-using-javascript-to-trap-focus-in-an-element)
  • use 3rd party solutions of focus trap, e.g. https://github.com/davidtheclark/focus-trap
  • use 3rd party solutions of modal windows, e.g. https://github.com/sweetalert2/sweetalert2 which is fully compatible with WAI-ARIA specifications and provide focus trap for you
like image 113
Limon Monte Avatar answered Oct 08 '22 08:10

Limon Monte


A non-jquery solution that cycles only through the modal's input elements


// place this line in the dialog show function - to only add the listener when the dialog is shown
window.addEventListener('keydown', handleKey);

// uncomment and place this in the dialog close/hide function to remove the listener when dialog is closed/hidden
// window.removeEventListener('keydown', handleKey);

function handleKey(e) {
    if (e.keyCode === 9) {
        let focusable = document.querySelector('#modal').querySelectorAll('input,button,select,textarea');
        if (focusable.length) {
            let first = focusable[0];
            let last = focusable[focusable.length - 1];
            let shift = e.shiftKey;
            if (shift) {
                if (e.target === first) { // shift-tab pressed on first input in dialog
                    last.focus();
                    e.preventDefault();
                }
            } else {
                if (e.target === last) { // tab pressed on last input in dialog
                    first.focus();
                    e.preventDefault();
                }
            }
        }
    }
}
like image 28
lilotop Avatar answered Oct 08 '22 07:10

lilotop


be careful of any method relying only on javascript events as it won't correctly handle screenreaders

However, this cannot be achieved without javascript like already indicated in multiple questions like How to keep focus within modal dialog?

You have three steps to do:

1. disable screenreader interaction with any other nodes by setting aria-hidden=true on them

For instance:

<main aria-hidden="true"><!-- main content here--></main>
<dialog>Your dialog here</dialog>

2. disable any keyboard interaction with them

This has to be done in Javascript / or jQuery.

This is a one-liner instruction in jQuery, using jquery-ui

$("main :focusable").addClass("disabled").attr("tabindex", -1);

The reverse can be achieved using:

$(".disabled").removeClass("disabled").attr("tabindex", 0);

3. remove any pointer event for those elements to disable mouse interaction

css sample:

main[aria-hidden='true'] { pointer-events: none;}
like image 28
Adam Avatar answered Oct 08 '22 09:10

Adam