Here's the backstory:
I'm currently in the process of creating a mobile-friendly widget for my clients. Unfortunately, they have web pages that are not optimized for mobile devices, and it doesn't seem like that will change anytime soon.
The Proposed Solution:
My initial idea was to take the widget out of the regular page flow by using position:fixed
, adding a viewport meta tag, and voila! Everything should work smoothly...right?
Check out this fiddle for reference.
The Issue at Hand:
However, the proposed solution seems to fail on certain mobile devices. My colleague experienced a situation where they could scroll away from the element marked as position:fixed
on their Android 4 or 5 device (so it's not the older 2.1-2.3 bug). It appears that iPhones exhibit similar behavior.
Essentially, it behaves more like position:absolute
positioned in the top-left corner of the page.
Further Details on the Proposed Solution:
I begin by injecting the viewport meta tag using JavaScript:
$('head').append('<meta name="viewport" content="width=device-width,initial-scale=1"/>');
Assume we have a simple HTML structure:
<html>
...
<div class="overlay">
<div class="modal">
<div class="content">...</div>
</div>
</div>
...
</html>
and the accompanying CSS:
.hide-overflow {
overflow: hidden;
}
.overlay {
position: fixed;
-webkit-backface-visibility:hidden; /* This may not be effective */
top: 0;
right: 0;
bottom: 0;
left: 0;
display: table;
overflow: hidden;
z-index: 1000;
}
.modal {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: table-cell;
text-align: center;
vertical-align: middle;
}
.content {
display: inline-block;
width: 800px;
height: 500px;
}
@media (max-width: 800px) {
.overlay * {
max-width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.content {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
}
Realizing that this might not suffice, I also included JavaScript to prevent scrolling on the <body>
and outer-most <div>
:
//This code is activated only when the widget is active and removed upon deactivation.
$('body').addClass('hide-overflow'); //Just sets overflow:hidden, in case you missed it ;)
$('body > div').addClass('hide-overflow');
On my Galaxy Note phone's default browser, everything works perfectly without any issues. However, it seems on iPhones, some Android devices, and so on, users can freely scroll away from the element styled with position:fixed
as if it were set as position:absolute
. How can I ensure that position:fixed
actually works as intended?