skip to Main Content

Consider the snippet below, where I’ve created a basic chat window.

The issue:
When you focus the input on a mobile device, the entire page is shifted up, pushing the header and messages out of view.

The goal: When you focus the input on a mobile device, the #messages section shrinks to accommodate the keyboard (similar to how the page behaves on desktop when reducing the window height).

(Images included below)

My attempts to resolve it: I’ve tried using height: 100% instead of 100dvh, I’ve tried moving the height declaration to the <body> instead of the <html>.

html,
body {
  padding: 0;
  margin: 0;
}

html {
  height: 100dvh;
  width: 100dvw;
}

body {
  height: 100%;
  width: 100%;
  background-color: white;
}

#content {
  height: 100%;
  display: flex;
  flex-direction: column;
}

#header {
  padding: 20px;
  background-color: #ccc;
}

#messages {
  margin: -10px 0;
  flex-grow: 1;
  flex-shrink: 1;
  overflow: auto;
}

.message {
  padding: 20px;
}

#footer {
  display: block;
  background-color: #aaa;
  padding: 20px;
}

input {
  padding: 5px;
  width: 100%;
  display: block;
}

button {
  border: 0;
  margin: 4px 0;
  padding: 4px;
  background-color: orange;
  font-weight: bold;
}
<div id="content">
  <div id="header">Header</div>
  <div id="messages">
    <div class="message"><b>John:</b> Lorem ipsum dolor sit amet.</div>
  </div>
  <form id="footer">
    <input>
    <button type="button">Send Message</button>
  </form>
</div>

This is the current behavior. The header and messages have been pushed up out-of-view.

Actual Behavior

This is the desired behavior. The header stays in place and the messages div shrinks to accommodate the keyboard.

Desired Behavior

EDIT: It seems this is a browser-specific issue. Firefox on mobile handles this perfectly. Chrome and Safari are not accounting for the onscreen keyboard when calculating dvh.

2

Answers


  1. Chosen as BEST ANSWER

    So, long story short, my code is actually fine. It's the browser behavior that needs to be manipulated.

    Adding interactive-widget=resizes-content to my page's <meta name="viewport"> tag solved the issue.

    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, interactive-widget=resizes-content">
    

    Reasons below:

    Here is the Chrome article detailing this change

    In November 2022, with the release of Chrome 108, Chrome will make some changes to how the Layout Viewport behaves when the on-screen keyboard (OSK) gets shown [...] and instead resize only the Visual Viewport.

    If you want your website to use the pre-108 resize behavior, fear not. Also shipping in Chrome 108 is an extension to the viewport meta tag.

    Through the interactive-widget key, you can tell Chrome which resize behavior you want.

    Accepted values for interactive-widget are:

    • resizes-visual: Resize only the Visual Viewport but not the Layout

    • resizes-content: Resize both the Visual Viewport and Layout

    • overlays-content: Do not resize any viewport.

    interactive-content


  2. I would of thought media queries would help with this:

        @media (max-width: 600px) { /* Adjust the max-width based on your requirements */
      #messages {
        max-height: 50vh; /* Example value, adjust as needed */
        overflow: auto;
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search