Prevent page jumping in Chrome when tabbing to offscreen elements
You don't need JS here, as Chrome supports scroll-behavior
property:
html { scroll-behavior: smooth;}
<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>
HTML/CSS cannot help in this matter, you have to take care of it with JavaScript. The simplest one I can think of is using Element.scrollIntoView()
method.
The Element.scrollIntoView() method scrolls the element on which it's called into the visible area of the browser window. It is experimental API as of today, but supported by most of modern browsers including chrome. (See Browser Support)
(function ($) { var shouldScroll = false; $(document).on('focus', 'input', function () { if (shouldScroll) { this.scrollIntoView(false); shouldScroll = false; } }); $(document).on('keydown', 'input', function (e) { if (e.keyCode == 9) shouldScroll = true; });})(jQuery);
<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>
Note: View the snippet in Full-Page/Expand-Snippet mode.
This is smooth for tabbing forward (tab) or backwards (shift+tab).
At first it is calculated which 'pixel' or 'index' is the first and the last visible one.
Then a comparison is made if the desired pixel/index fits within that range.
If not -> an adjustment is done.
$('input').focusin(function(e) { let height = $(window).height(); let scroll = $(window).scrollTop(); let position = $(this).position().top; let elementHeight = $(this).height(); let firstVisibleIndex = scroll; let lastVisibleIndex = scroll + height; let additionalSpace = 5 * elementHeight; let newScrollTop; if(position + additionalSpace > lastVisibleIndex) { newScrollTop = position - height + additionalSpace; } if(position - additionalSpace < firstVisibleIndex) { newScrollTop = position - additionalSpace; } $(window).scrollTop(newScrollTop);});