Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adjust flex layout height for mobile device

Tags:

html

css

mobile

I have a layout that is similar to a console where there is a menu bar on top, an input line in the bottom, and in the middle there is a scrolling div with text that gets added as you type.

let pre = $("pre")
for (let i = 0; i < 200; i++) {
    pre.append("<span class='line'>line " + i + "</span>")
}
function bottom() {
    pre.scrollTop(pre.prop("scrollHeight"));
}
$("#commandline").on('keyup', function (e) {
  if(e.which == 13){
    pre.append("<span class='line'>" + $("#commandline").val() + "</span>");
    bottom();
    $("#commandline").val("");
  }
});
bottom();
html, body {
  top: 0;
    right: 0;
    left: 0;
    bottom: 0;
    overflow: hidden;
    position: absolute;
}


#container {
      position: absolute;
    top: 0;
    right: 0;
    left: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

#toprow, #bottomrow {
  flex: none;
  background-color: red;
}

#midrow {
  flex: 1;
    display: flex;
    position: relative;
}

pre {
  overflow-y: scroll;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: 0;
  box-sizing: border-box;
}

.line {
  display: block;
}

#commandline {
  position: relative;
  width: 100%;
  border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
  <body>
    <div id="container">
      <div id="toprow">
        Menubar
      </div>
      <div id="midrow">
        <pre>
          <span>ton of lines</span>
        </pre>
      </div>
      <div  id="bottomrow">
        <input type="text" id="commandline">
      </div>
    </div>
  </body>
</html>

It all works fine in a normal browser. And it also renders fine in a mobile browser as long as you don't focus into the input box. When you do that the onscreen keyboard pops up and shifts the top of the ui outside of the remaining viewport instead of adjusting the height of the window to fill the remaining space.

You can see how that can break everything because there is a scrolling div in the middle, so you cannot scroll up to get to the menubar anymore until you scroll the whole middle pre up to the top.

I need this layout to always fill the remaining space on the screen, not shift up when the keyboard appears.

I tried in the Chrome dev tools by emulating th device Nexus 5, and there it seems to work, but when trying to test this on a Samsung S20 in mobile Chrome it doesn't.

Can somebody help to figure out a layout that works responsively with the on screen keyboard on a mobile?

Here is the JsFiddle: https://jsfiddle.net/cpzqf9vo/1/

Bonus point: is there a way to remove the adressbar from the mobile browser?

like image 858
Marino Šimić Avatar asked Jun 24 '26 04:06

Marino Šimić


1 Answers

To make the header resting at the top while typing on IOS, make your textbox fixed to the bottom and avoid position:relative; as much as possible. In your case the CSS should be something similar to this:

#commandline {
    position: fixed;
    bottom: 0;
    width: 100%;
}

CSS fixed bottom is supported by most of the modern mobile browsers (2023):

Browser Compatibility on caniuse for CSS fixed

The output before resolving the issue:

A Screen recorded Demo of the original/unresolved code

Also in your case, avoiding position:relative; helps because it decides the position based on the element's original position. Here is the output after resolving the issue:

enter image description here

Here's the fully fledged code of the solution which has been tested on iPhone 12, 14 Pro Max and 15.

let pre = $("pre")
for (let i = 0; i < 200; i++) {
    pre.append("<span class='line'>line " + i + "</span>")
}
function bottom() {
    pre.scrollTop(pre.prop("scrollHeight"));
}
$("#commandline").on('keyup', function (e) {
  if(e.which == 13){
    pre.append("<span class='line'>" + $("#commandline").val() + "</span>");
    bottom();
    $("#commandline").val("");
  }
});
bottom();
html {
    min-height: 100%;
    
}

body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    padding: 4px;
}

#toprow {
    width: 100;
    background-color: #eee;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1;
    color: white;
}

#toprow, #bottomrow {
    flex: none;
    background-color: red;
}

#bottomrow{
    position: absolute;
    left: 0px;
}

#container {
    flex: 1;
}

.line {
  display: block;
}

#commandline {
    border: 1px solid red;
    position: fixed;
    bottom: 0;
    width: 100%;
}

pre {
  overflow-y: scroll;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: 0;
  box-sizing: border-box;
}

* {
    box-sizing: border-box;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
  </head>
  <body>  <div id="toprow">
        &nbsp;JAYANIKA.COM
      </div>
<div id="container">
   <div id="midrow">
      <pre>
          <span class="line">ton of lines</span>
      </pre> 
   </div>
</div>
      
       <div  id="bottomrow">
        <input type="text" id="commandline">
      </div>
      </body>
</html>

For your reference:

Fix element to bottom of screen

Why is my position:sticky not working on iOS?

like image 178
Jayanika Chandrapriya Avatar answered Jun 25 '26 21:06

Jayanika Chandrapriya



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!