Android Keyboard shrinking the viewport and elements using unit vh in CSS

height: 100vh not working in safari
chrome mobile address bar height
mobile safari address bar height
ios viewport scroll bug
css vh support
ios viewport height keyboard
100vh mobile
css detect mobile keyboard

I am experiencing a very strange and unique issue.

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

Issue: On Android tablets, when you touch the input field the default keyboard pushes the view port which is causing the page and all the elements in the page to shrink.

On ipad this issue does not exist since the keyboard overlaps the screen and does not push the screen.

Looking for any solution to avoid the Android keyboard not to push the viewport of the browser and keep the original size.

Note: The only option i am left with is to avoid keyboard to push viewport, i won't be able to change the CSS units or use xml, manifest. These are web pages which experiencing this issue.

I know this is an old question, but I had the exact same problem in my app. The solution I found was fairly simple. (My app is in Angular so I put this in the app.component's ngOnInit function, but document.ready() or any other "initialization complete" callback should work just fine with the proper 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 the viewport meta to explicitly set viewport height, whereas hardcoding

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

doesn't work because the device-width and device-height change when Android's soft keyboard is opened.

Using keyboard on inputs causes viewport to resize, shrinking , Using keyboard on inputs causes viewport to resize, shrinking elements based on viewport units. Summary: Firefox for Android ▾. Firefox for Android. In JavaScript, you can always get the value of the current viewport by using the global variable window.innerHeight. This value takes the browser's interface into account and is updated when its visibility changes. The trick is to store the viewport value in a CSS variable and apply that to the element instead of the vh unit.

I faced the same problem recently, and it took me time to find a nice solution. I am designing a cordova app using html5, css3 and angularjs. But moreover, I want my app to fit every screen without writing tones of media queries and finally unreadable css. I started with viewport and vh, but the keyboard broke eveything.

So what you have to use is just a little javascript (here is jquery) like this :

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

Here you go, now you can use "rem" exactly the same way you are using "vh", except that the viewport will not affect font-size. "Rem" is set on html root font-size only and we just set it with jquery to 1% of the screen height.

Hope this will help!

EDIT 1 : I just faced a new problem, so I give my solution here. Most of the time, smartphones have a minimum limit for font-size. You have to change all your rem value, and divide it by 3 or 4. Then, you have to change the javascript with :

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

It is even easier if you are using SASS, you can create a rem function which will do division for you.

The trick to viewport units on mobile, All my pages are using vh and vw CSS units instead of px due to the nature of the project. Issue: On Android tablets, when you touch the input field the default  When the address bar scrolls out of the viewport and then again when scrolls into the viewport, the viewport height changes. This causes any element using vh to recalculate which makes the page jump. It's extremely annoying when using a background image because it causes the image to resize on scrolling.

In Angular 4+

import {Meta} from "@angular/platform-browser";

constructor(private metaService: Meta){}

ngOnInit() {
  name: 'viewport',
    content: `height=${this.height}px, width=${this.width}px, initial-scale=1.0`

Keep the element height when the viewport is resized, vh unit. Equal to 1% of the height of the initial containing block. As of this writing, there is a ticket to address this in Firefox Android. An element gets cropped at the bottom when the address bar is in In JavaScript, you can always get the value of the current viewport by using the global variable window. That’s a detail, though—the cool stuff is simply setting element sizes with vh. This feels like the height: 100%; CSS element that should’ve worked the whole time—although, sadly, it only works relative to the browser. (For more options that are relative to a containing element, have a look at Flexbox.)

You could use % which doesn’t seems to be affected by this issue or vw (not affected for obvious reason) even for height.

Issues with vh and mobile keyboards in Telerik AppBuilder , Keep the element height when the viewport is resized on mobile browsers. you maintain your element's height when using vh units (viewport height) bar being shown/hidden or keyboard open/close, preventing unexpected $element.css('​height', '100vh'); // Change this to your own original vh value. If you use viewport length units in your CSS within the iframe document, 1vh will be 1% of the height of the iframe, and 1vw will be 1% of the width of the document. If the iframe is set to 50vw, it will be 50% of the width of the 1200px parent document in our example above, or 600px, with 1vw being 6px.

Nearly a year to late, but I want also to share my solution to this more and more important problem.

I created a small JS function SET which is loaded after the DOM is completed.

Every Element assigned to a special class (In this case ".pheight") doesn't resized when the viewport height decreases. It is only allowed to resize if the viewport height increases or the viewport width changes.

So in my Applications it works perfectly!

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

Android Viewport and the Soft Keyboard : webdev, I am experiencing a very strange and unique issue. All my pages are using vh and vw CSS units instead of px due to the nature of the project. How can you use new CSS units — viewport units — to size content that changes in response to the viewport size? Jen introduces you to how vw, vh, vmin, vmax can be used in creative ways.

Mobile Chrome vh units fix · Muffin Man, It would also be great if I can fix this simply through css styling. When the keyboard is shown, all elements that use the vh css3 unit of measurement are affected. viewport height, and when the keyboard is shown, the pictures shrink due The differences on iPhone and Android probably didn't matter as  And then getting the height using jquery shows CORRECT results on Android - aka the visible viewport size WITHOUT the virtual keyboard, but not on iOS. I am getting a random number, which I assume stems from the rest of the meta tag not existing, so I am getting a zoomed-in version of the website along with a number like 75 or 100 (on iphone 4s)

Android keyboard resize viewport, It makes using vh units a waste of time so why even support them. Resizing the viewport makes sure any input field is visible when using the keyboard, while I wanted to explore recently, as well as Tailwind CSS for the uber-cool utility classes. with incrementing the rotation by 90 degrees every time I click an element? The app uses an img element that is set to use the viewport values for width and height. Yet the behavior is different in both platforms. For iOS the viewport is still resized, but the image keeps its original dimensions even when the keyboard is show. For Android the fix prevents the viewport from resizing. Let me know if this works for you. Regards,

on Android or iOS. * Android Chrome has a bug, when keyboard pops up, it triggers orientation change. Every object should have CSS selector and height in vh units. All elements that match given selector will be fixed. var options = [ { selector: '. only frame animations · 02 Mar 2019 Hiding body scrollbars using CSS  This causes an annoying flickering of on-screen viewport sized elements as the keyboard appears, and while the keyboard is active, everything sized in vh is about half normal size. It'd be nice if Firefox didn't do that. snorp says it is to ensure the edited element is visible.

  • Perfect solution! Worked like a charm. I tried on which is a landing page split into section, where each have a 100vh height. Thanks!
  • This Solution works fine, but I discovered a small problem. When working with the chrome developer tools in mobile-device-emulation mode the values of window.innerHeight and window.innerWidth (or $(window).height() and $(window).width()) are not set correctly. So if you are working with this tool, you should query window.visualViewport.height and window.visualViewport.width when your code runs in the development browser.
  • window stops being scrollable on input if page is less than or equal to viewport
  • Yup this should be the answer. @madeinstefano I just checked your site, it's weird I can still pinch to scale the site. In order to be friendly, add maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui in the viewport also.
  • you don't need to specify the "px" .