I have a pop-up/overlay that appears on 'click' of an element. Because there is plenty of HTML content behind the pop-up the buttons/input elements on the pop don't naturally have focus/tabindex behaviour. For accessibility reasons I would like it so that when this pop us shows the elements inside the modal have focus/tab index priority not the main content behind it.
In the simple demonstration below - after you click the 'click-me' button, when you use the tab key the browsers still tabs through the input elements behind the overlay.
Any suggestions on how to give the overlay the tab behaviour when it shows would be greatly appreciated.
Creating a focus
event on the modal doesn't seem to work?
Codepen: https://codepen.io/anna_paul/pen/eYywZBz
EDIT
I can almost get George Chapman's Codepen answer to work, but when you hold the enter key down it flashes back and forth between the overlay appearing and not appearing, and it doesn't seem to work in Safari?
let clickMe = document.querySelector('#click-me'),
modal = document.querySelector('.modal'),
closeButton = document.querySelector('.close')
clickMe.addEventListener('click', () => {
modal.style.display = 'flex';
// modal.focus();
})
closeButton.addEventListener('click', () => {
modal.style.display = 'none';
})
body {
margin: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
input, button {
margin: 1rem;
padding: .5rem;
}
.click-me {
display: block;
}
.modal {
display: none;
flex-direction: column;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
background: grey;
position: absolute;
}
form {
display: flex;
}
<button id="click-me">Click Me</button>
<form action="">
<input type="text" placeholder="An Input">
<input type="text" placeholder="An Input">
<input type="text" placeholder="An Input">
<input type="text" placeholder="An Input">
</form>
<div class="modal">
<button class="close">Close x</button>
<button>More Buttons</button>
<button>More Buttons</button>
</div>
You have to add focus to the pop-up right after this appears, when you do it simultaneously with closeButton.focus()
only it won't work that's why I'm using setTimeout(() => closeButton.focus(), 1)
, this will added it focus after a 1
millisecond.
At first, focus on a button isn't visible, it become visible when arrow keys are pressed, so I make it visible styling it:
.close:focus {
border: 2px solid black;
border-radius: 5px;
}
The whole code:
let clickMe = document.querySelector("#click-me"),
modal = document.querySelector(".modal"),
closeButton = document.querySelector(".close");
clickMe.addEventListener("click", () => {
setTimeout(() => closeButton.focus(), 1);
modal.style.display = "flex";
});
closeButton.addEventListener("click", () => {
modal.style.display = "none";
});
body {
margin: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
input,
button {
margin: 1rem;
padding: 0.5rem;
}
.click-me {
display: block;
}
.modal {
display: none;
flex-direction: column;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
background: gray;
position: absolute;
}
form {
display: flex;
}
.close:focus {
border: 2px solid black;
border-radius: 5px;
}
<button id="click-me">Click Me</button>
<form action="">
<input type="text" placeholder="An Input" />
<input type="text" placeholder="An Input" />
<input type="text" placeholder="An Input" />
<input type="text" placeholder="An Input" />
</form>
<div class="modal">
<button class="close">Close x</button>
<button>More Buttons</button>
<button>More Buttons</button>
</div>
UPDATE: The focus jumps only within the modal:
let clickMe = document.querySelector("#click-me"),
modal = document.querySelector(".modal"),
closeButton = document.querySelector(".close");
lastButton = document.querySelector(".lastButton");
clickMe.addEventListener("click", () => {
setTimeout(() => closeButton.focus(), 1);
modal.style.display = "flex";
});
closeButton.addEventListener("click", () => {
modal.style.display = "none";
});
modal.addEventListener("keydown", function (event) {
var code = event.keyCode || event.which;
if (code === 9) {
if (lastButton == document.activeElement) {
event.preventDefault();
closeButton.focus();
}
}
});
body {
margin: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
input,
button {
margin: 1rem;
padding: 0.5rem;
}
.click-me {
display: block;
}
.modal {
display: none;
flex-direction: column;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
background: gray;
position: absolute;
}
form {
display: flex;
}
.close:focus {
border: 2px solid black;
border-radius: 5px;
}
<button id="click-me">Click Me</button>
<form action="">
<input type="text" placeholder="An Input" />
<input type="text" placeholder="An Input" />
<input type="text" placeholder="An Input" />
<input type="text" placeholder="An Input" />
</form>
<div class="modal">
<button class="close">Close x</button>
<button>More Buttons</button>
<button class="lastButton">More Buttons</button>
</div>