Android does not correctly scroll on input focus if not body element
This is a bug in the Android native browser. By the way, the input scrolls into the view after a character is typed on the soft keyboard.
The following code snippet placed somewhere in the page should help:
if(/Android 4\.[0-3]/.test(navigator.appVersion)){ window.addEventListener("resize", function(){ if(document.activeElement.tagName=="INPUT"){ window.setTimeout(function(){ document.activeElement.scrollIntoViewIfNeeded(); },0); } })}
The answer from Serge is great but I had a few modifications that improved it for me.
The problem appeared on Android 6 for me as well so I added it to the check and I needed the fix to work for textareas as well as inputs.
if(/Android [4-6]/.test(navigator.appVersion)) { window.addEventListener("resize", function() { if(document.activeElement.tagName=="INPUT" || document.activeElement.tagName=="TEXTAREA") { window.setTimeout(function() { document.activeElement.scrollIntoViewIfNeeded(); },0); } })}
If anyone needs the fix in Angular 1, here is what I used there.
angular.module('<module name>').run(function ($window, $timeout) { if(/Android [4-6]/.test($window.navigator.appVersion)){ $window.addEventListener("resize", function(){ if(document.activeElement.tagName=="INPUT" || document.activeElement.tagName=="TEXTAREA"){ $timeout(function() { document.activeElement.scrollIntoViewIfNeeded(); }); } }); }});
Offering slight revision if it saves anyone some time:
- No need to specify an Android version # (less likely to break when your user gets Android 7.0+)
- No need to wrap in a setTimeOut
MDN advises against
.scrollIntoViewIfNeeded
bc of browser incompatibility =>.scrollIntoView
is a workable substitute with slightly more browser compatibilityif(/Android/.test(navigator.appVersion)) { window.addEventListener("resize", function() { if(document.activeElement.tagName=="INPUT" || document.activeElement.tagName=="TEXTAREA") { document.activeElement.scrollIntoView(); } })}