When using transform: translate to animate a drawer in & out, pressing the tab key in Chrome will alter the layout of the page to bring the hidden drawer contents into focus.
The solution that almost works: add visibility: hidden to the drawer when it's closed, preventing its elements from being focusable. However the drawer must be visible during the close animation. Therefore pressing tab during the closing animation reproduces the issue.
https://jsfiddle.net/uje5m1o8/6/
The toggle button's position is now permanently incorrect. It moves upward off screen.
I'm looking for a way to stop this from happening. I'd prefer for this to work with an arbitrary amount of contents within the drawer, so manually adding tabIndex=-1 to everything in the drawer isn't preferable.
Add a check to see if the animation is in progress and prevent navigation with tab during that time. There might be a nicer solution though.
let animInProg = false
const toggle = () => {
anim()
const drawer = document.querySelector('#drawer')
drawer.classList.toggle('drawer-open')
drawer.classList.toggle('drawer-closed')
}
const toggleButton = document.querySelector('#toggle-button')
toggleButton.addEventListener('click', toggle)
function anim(){
animInProg = true;
return setTimeout(()=>{
animInProg = false;
}, 500)
}
document.addEventListener('keydown', (e)=>{
if(animInProg && e.key == 'Tab'){
e.preventDefault()
}
})
#interaction-box {
width: 80%;
height: 200px;
margin: auto;
background-color: cyan;
position: relative;
overflow: hidden;
}
#drawer {
position: absolute;
bottom: 0;
background-color: red;
width: 100%;
height: 50%;
display: flex;
justify-content: center;
align-items: flex-end;
}
.drawer-closed {
transform: translateY(100%);
visibility: hidden;
transition: visibility 0ms 500ms, transform 500ms ease-in-out;
}
.drawer-open {
transition: transform 500ms ease-in-out;
}
<div id="interaction-box">
<button id="toggle-button">
Toggle Drawer
</button>
<br />
Text 1
<br />
Text 2
<br />
Text 3
<br />
Text 4
<br />
Text 5
<br />
Text 6
<br />
Text 7
<br />
Text 8
<br />
Text 9
<div id="drawer" class="drawer-closed">
<button>
Button Inside Drawer!
</button>
</div>
</div>