Yes and no. There is no way to prevent the parent from scrolling to the focused element (which I know). However, you can undo scrolling by scrolling back the parent element. Done correctly, it will not be noticeable to the user.
To do this, anytime you programmatically focus an element, extract the current scroll offset of the focused parent node element and set scrollTop to that offset.
var children = document.getElementsByClassName('child') for (var i = 0; i < children.length; i++) { children[i].addEventListener('click', function (e) { e.preventDefault var focused = document.getElementById('focus') var focusedParent = focused.parentNode var savedOffset = focusedParent.scrollTop focused.focus(); focused.parentNode.scrollTop = savedOffset; }) }
.parent { height: 300px; overflow: auto; } .child { height: 50px; background-color: gray; border-bottom: 1px solid black; color: white; box-sizing: border-box; text-align: center; line-height: 50px; font-family: Arial; }
<div class="parent"> <div class="child" tabIndex="-1">1</div> <div class="child" tabIndex="-1">2</div> <div class="child" tabIndex="-1">3</div> <div class="child" tabIndex="-1">4</div> <div class="child" tabIndex="-1">5</div> <div class="child" tabIndex="-1">6</div> <div class="child" tabIndex="-1">7</div> <div class="child" tabIndex="-1">8</div> <div class="child" tabIndex="-1" id="focus">9</div> <div class="child" tabIndex="-1">10</div> </div>
Here's a working demo on Codepen .
source share