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>