1

For a web application I maintain, I recently introduced a fixed bottom menu bar. Via position:fixed this menu remains affixed to the bottom of the viewport as the user scrolls.

However, when the user encounters a textarea or input field and tries to focus on it, the virtual keyboard pops open, pushing the aforementioned fixed menu bar up top. Several times, this mechanic ends up covering the textarea or input in its entirety - giving rise to a huge usability issue.

To fix it, I wrote a simple pure JS solution whereby I set position:fixed to position:absolute on focus, and return it to position:fixed on blur. The solution has been explored indepth in this SO question.

This solves the problem to an extent, but the solution is erratic. Let me show you how.


The following code implements the solution I explained above. Run the code snippet. And then, focus the textarea right under Sample text 2. This toggles the bottom menu bar from fixed to absolute, and there's a nasty visual jump caused by this. It exacerbates if you try the same in textareas further below.

How can I avoid the nasty visual jump? Ideally I want the fixed navbar to toggle to absolute in a way that keeps sticking it to the bottom of my viewport. Is that possible? Would love to see an example from experts in this regard.


var input_btns = document.getElementsByClassName('inp');// selecting all textareas or inputs for processing (e.g. making fixed bottom menu 'absolute')
for (var i=0, len=input_btns.length; i < len; i++) {
 input_btns[i].onfocus = () => {
  var bottom_nav = document.getElementById("bottom_nav")
  bottom_nav.classList.remove('fix-it');
       bottom_nav.classList.add('abs-it');
 }
 input_btns[i].onblur = () => {
  var bottom_nav = document.getElementById("bottom_nav")
  bottom_nav.classList.remove('abs-it');
       bottom_nav.classList.add('fix-it');
 }
}
.fix-it{
  position: fixed;
 }
 .abs-it{
  position: absolute;

 }
<div>
Sample text 1<br><br>

<textarea class="inp" style="width:100%"></textarea>

</div>
<div>
Sample text 2<br><br>

<textarea class="inp" style="width:100%"></textarea>

</div>
<div>
Sample text 3<br><br>

<textarea class="inp" style="width:100%"></textarea>

</div>
<div>
Sample text 4<br><br>

<textarea class="inp" style="width:100%"></textarea>

</div>
<div>
Sample text 5<br><br>

<textarea class="inp" style="width:100%"></textarea>

</div>
<div>
Sample text 6<br><br>

<textarea class="inp" style="width:100%"></textarea>

</div>
<div>
Sample text 7<br><br>

<textarea class="inp" style="width:100%"></textarea>

</div>
<div id="bottom_nav" class="fix-it" style="background:coral;z-index:89;bottom:0;height:56px;width:100%;text-align:center;border-top:1px solid #dddddd">
BOTTOM MENU BAR
</div>
Hassan Baig
  • 15,055
  • 27
  • 102
  • 205
  • "sticky" position instead of "fixed" might help here; worth a try. But mobile phones smashing up your layout when the virtual keyboard opens (or the browser's footer bar, or its top location bar, both of which are selectively shown on some browsers) seems to be a fact of life which isn't completely avoidable, only mitigatable (in my painful experience, anyway). – avocadatoria Feb 22 '20 at 19:42
  • @avocadatoria: no, `sticky` has some quirks too (plus compatibility issues that make me uncomfortable). Part of me is now thinking I should just apply `display:none` when the virtual keyboard is called - and be done with it -_- – Hassan Baig Feb 23 '20 at 09:19

0 Answers0