Android keyboard shortens viewport and elements with vh module in CSS

I have a very strange and unique problem.

All my pages use vh and vw CSS units instead of px due to the nature of the project.

Problem. On Android tablets, when you touch the input field, the keyboard by default clicks on the view port, which causes the page and all the elements on the page to be compressed.

In ipad, this problem does not exist, because the keyboard overlaps the screen and does not click on the screen.

You are looking for any solution to avoid the Android keyboard, so as not to click on the browser window and keep the original size.

Note. The only option I stay with is to avoid the keyboard to press viewport, I will not be able to change CSS units or use xml, manifest. These are web pages that are experiencing this problem.

+18
source share
6 answers

I know this is an old question, but I had the same problem in my application. The solution I found was pretty simple. (My application is in Angular, so I put this in the app.component ngOnInit function, but document.ready() or any other "completion" callback should work fine with the right experimentation)

 setTimeout(function () { let viewheight = $(window).height(); let viewwidth = $(window).width(); let viewport = document.querySelector("meta[name=viewport]"); viewport.setAttribute("content", "height=" + viewheight + "px, width=" + viewwidth + "px, initial-scale=1.0"); }, 300); 

This forces viewport metadata to explicitly set the height of the viewport, whereas hardcoding

 <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1"> 

does not work because changing the width of the device and the height of the device when opening the soft keyboard Android.

+22
source

I have been facing the same problem recently and it took me a while to find a good solution. I am developing a cordova application using html5, css3 and angularjs. But besides that, I want my application to fit every screen without writing the tones of media queries and finally unreadable css. I started by browsing and vh, but the keyboard broke everything.

So you just need a little javascript (here is jQuery):

 $("html").css({"font-size": ($(window).height()/100)+"px"}); 

Here you go, now you can use "rem" just like you use "vh", except that the viewport does not affect the font size. "Rem" is set only to the html root font size, and we just set it with jquery to 1% of the screen height.

Hope this helps!

EDIT 1: I just ran into a new problem, so I offer my solution here. In most cases, smartphones have a minimum limit on font size. You should change all your rem value and divide by 3 or 4. Then you should change javascript with:

 $("html").css({"font-size": ($(window).height()/25)+"px"}); /*(this is if you divide with 4)*/ 

Even easier, if you use SASS, you can create a rem function that will perform the separation for you.

+1
source

In angular 4+

 import {Meta} from "@angular/platform-browser"; constructor(private metaService: Meta){} ngOnInit() { this.metaService.updateTag({ name: 'viewport', content: 'height=${this.height}px, width=${this.width}px, initial-scale=1.0' }, 'name='viewport'' ); } 

0
source

You can use%, which does not seem to be affected by this problem, or vw (not affected for obvious reason) even for height.

0
source

Almost a year until the end, but I also want to share my solution to this increasingly important problem.

I created a small JS SET function that loads after the DOM completes.

Each element assigned to a special class (in this case ".pheight") does not change when the height of the viewport decreases. Resizing is possible only when increasing the height of the viewing area or when changing the width of the viewing area.

So in my applications this works great!

  var docwidth = window.innerWidth; var docheight = window.innerHeight; function pheigt_init() { pheigt_set_prevent_height(); window.onresize = function() { if (docwidth !== window.innerWidth || docheight < window.innerHeight) { pheigt_upd_prevent_height(); } }; } function pheigt_set_prevent_height() { document.querySelectorAll('.pheight').forEach(function(node) { node.style.height = node.offsetHeight + 'px'; }); } function pheigt_upd_prevent_height() { document.querySelectorAll('.pheight').forEach(function(node) { node.style.removeProperty('height'); }); setTimeout(function(){ pheigt_set_prevent_height(); }, 100); docheight = window.innerHeight; docwidth = window.innerWidth; } document.addEventListener('DOMContentLoaded', pheigt_init()); 
0
source

The same problem took me a step. I did not find any css solution or workaround to solve the problem.

However, if you can use jQuery (or almost JavaScript), I have code that you can use to resolve it.

 var viewportHeight = $(window).height(); var viewportWidth = $(window).width(); $('body,html').css("height",viewportHeight); //if vh used in body/html too $('.someClass').css("height",viewportHeight*0.12);// or whatever percentage you used in vh $('#someId').css("width",viewportWidth*0.12); 

Well, this is just an example, you can use the jQuery percent identifiers you need.

PD: There is one tip for your information. put the code in the final of your html or inside $ (document) .ready (function () {}) ;, and if you need a responsive design, put it also inside the changechange event; in this way.

 $(window).on("orientationchange",function(event){ window.setTimeout(function(){ var viewportHeight = $(window).height(); var viewportWidth = $(window).width(); $('body,html').css("height",viewportHeight); $('.someClass').css("height",viewportHeight*0.12); $('.someClass').css("width",viewportWidth*0.09); $('#someId').css("height",viewportHeight*0.1); }}, 450);}); 

I set the timer 450ms higher due to the delay of devices performing orientation changes.

Sorry for my english greetings

-1
source

All Articles