I have a mobile web app that displays a dialog box within a position: fixed element overlaying the entire screen. No matter how much content is displayed or how far the page has scrolled, the overlay element dims the page content and the dialog appears on top of it all. There is an <input type="search />
field in the dialog.
On Android, when the user taps the input field to give it focus, some pretty erratic behavior often (but not always) ensues:
This is on Android 2.3.4 with the built-in browser. It may also occur on other Android versions.
The page constructed something like this: (Keep in mind that some of these quirks only show up when the page contains enough content to allow scrolling.)
<head>
<style type="text/css">
#menuoverlay {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 10;
background-color: rgba(0,0,0,.75);
text-align: center;
}
#menu {
display: inline-block;
margin-top: 1em;
border: 3px solid #02b;
border-radius: 8px;
padding: 1ex;
background-color: black;
color: silver;
}
</style>
</head>
<body>
<div id="menuoverlay">
<div id="menu">
...menu items...
...menu items...
<form action=""><input type="search"/></form>
</div>
</div>
<div id="content">
...lots of stuff...
...lots of stuff...
...lots of stuff...
</div>
<body>
Has anyone else seen this behavior? Have you found a way to prevent it?
Scouring the web led me to a few reports of similar problems. Here's a summary of what I have read so far:
transform: translate3d()
, -webkit-backface-visibility
, or position: fixed
.Here are some relevant links:
Android Browser textarea scrolls all over the place, is unusable
How can I style an HTML INPUT tag so it maintains CSS when focused on Android 2.2+?
Android 2.2/2.3’s Native Browser and Fixed Positioning
I managed to prevent the momentary overlay shift by setting outline: none
on my input
element.
I got the wild page scrolling and disappearing keyboard to settle down by setting overflow: hidden
on the html body
when showing the dialog, and then removing it again when hiding the dialog. This has a nasty side effect of resetting the page's scroll position, so I save it and restore it as necessary, and wrap all this hackery in conditionals so it only runs on Android. (I hope my Android users won't be too distracted when they see the page contents change beneath the semi-transparent overlay while the dialog is open.)
Interestingly, I was also able to prevent the wild page scrolling by catching the touchstart
event on my overlay element and calling preventDefault(). This makes me wonder if all this madness was caused by a sequence of events like this:
touchstart
bubbles up to the document roottouchstart
where the duplicate input field was placedI didn't end up catching touchstart
to solve the problem, because it prevented the input field from gaining focus, and calling focus()
from javascript just didn't work. I have read that the Android browser disables the focus()
method on input fields, which would explain this behavior. Perhaps it does this because it wouldn't work with the duplicate text widgets it creates over the html-defined fields.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With