Saturday, 28 July 2018

Prevent page jumping in Chrome when tabbing to offscreen elements

Run the following in Chrome, and repeatedly press the Tab key.
<ol>
  <li><input type="text" autofocus></li>
<li><input type="text"></li>
<li><input type="text"></li>
<li><input type="text"></li>
<li><input type="text"></li>
<li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text">
</li><li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
</ol>
Note how the page jumps up whenever you get to the bottom of the screen. I'd rather the page scroll up smoothly.
I can prevent this behavior with JavaScript:
$(document).on('focus', 'input', function() {
  let top = $(this).parent().position().top,
      scroll = $(window).scrollTop(),
      inputHeight = $('input').height(),
      windowHeight = $(window).height();

  if (top < scroll + inputHeight) {
    window.scrollBy(0, -inputHeight);
  } else if (top > scroll + windowHeight - inputHeight * 2) {
    window.scrollBy(0, inputHeight);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ol>
  <li><input type="text" autofocus></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li><li><input type="text"></li>
<li><input type="text"></li><li><input type="text"></li>
</ol>
But I'm wondering if there is an HTML or CSS solution. (I would also settle for a more elegant JavaScript solution.)


from Prevent page jumping in Chrome when tabbing to offscreen elements

No comments:

Post a Comment