Fixed element flicker within an iframe on iOS - ios

I know there seems to be a lot out there about this, but none of the solutions seem to fix my issue.
I am trying to apply a fixed button to the bottom of my screen within an iframe. With my current implementation, I am experiencing a terrible flicker with the button on iOS Safari whenever I scroll.
Here's essentially what I have:
HTML
<iframe>
<body>
<div class="app">
<div class="app-content">
<div class="card">
<h1>Header</h1>
<p>Content</p>
</div>
<button class="fixed-button">This is flickering</button>
</div>
</div>
</body>
</iframe>
CSS
iframe {
border: none;
position: absolute;
height: 100%;
width: 100%;
top: 0; left: 0;
}
app {
-webkit-overflow-scrolling: touch;
overflow:auto;
position:absolute;
width:100%;
height:100%;
}
fixed-button {
position: fixed;
bottom: 1rem;
}
I've got a WIP on my site here http://jaredrauh.com/iframe-fixed-elements-ios/. Any suggestions would be amazing.

Related

Why my image doesn't go on height on mobile?

I would the image on desktop to stay the same, but on mobile to be bigger on height. What should i change in the code ? I'm using Bootstrap 5 aswell.
<div class="container">
<div class="row">
<div class="col-12">
<img src="/images/section1/home-image.jpg" class="img-fluid" id="img1" alt="man on boat">
<img src="/images/section1/home-logo.png" class="img-fluid" id="img2" alt="logo Seafarer">
</div>
</div>
</div>
#section1 {
position:relative;
}
#img2 {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
Here you go...
I think this is impossible to achieve with Bootstrap. I would use #media query if I were you.
Add this to your CSS:
#media only screen and (max-width: 575px) {
.col-12 {
height: 500px; // Adjust the height
}
#img1 {
object-fit: cover;
height: 100%;
}
}
It's important to add object-fit: cover; otherwise your image will be screwed. Try to remove this line to see what I'm talking about.
Let me know if this is helpful.

Scrolling X not possible on iOS

When i load the screen on iOS scrolling in the X axis is not possible on iOS. No issues on android. When clicking a button which refreshes the data on the screen scrolling is possible again.
Anybody an idea what could cause this?
<div class="container">
<!-- CONTENT -->
<div class="scroll-container">
<!-- CONTENT-->
</div>
</div>
CSS
.container {
overflow-y: scroll;
width: 100%;
position: absolute;
overflow-x: scroll;
}
.scroll-container {
min-width: 100%;
overflow: scroll;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
display: inline-block;
padding-bottom: 50px;
}
According to the docs you can add a scrolling section in your content using ion-scroll:
ion-scroll
Scroll is a non-flexboxed scroll area that can scroll horizontally or
vertically. ion-scroll Can be used in places where you may not need a
full page scroller, but a highly customized one, such as image scubber
or comment scroller.
<ion-scroll scrollX="true" scrollY="true">
<!-- ... -->
</ion-scroll>
Demo source:
<ion-header>
<ion-navbar>
<ion-title>Scroll</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-scroll scrollX="true" scrollY="true" style="width: 100%; height: 100%">
<div class="map-div"></div>
</ion-scroll>
</ion-content>
<style>
.map-div {
width: 2600px;
height: 1400px;
background: url('./assets/map.jpeg') no-repeat;
}
</style>

iOS Input field scrolls to top when focussed

I have created a demo (not in Jsfiddle, couldn't get it to work in device):
http://i283951.iris.fhict.nl/test.html
When I open this on my iPad and scroll down all the way and then click on the input, it scrolls all the way up to the top and then shows the keyboard.
I'm pretty sure this also happens with a iPhone, on my android I don't have those problems. So I think it's iOs related.
body {
margin: 0;
padding: 0;
height: 2000px;
}
.top {
width: 100%;
height: 50px;
position: fixed;
background-color: #AA3939;
}
.input-group {
margin-top: 12px;
margin-left: 50px;
}
<html>
<head>
</head>
<body>
<div class="top">
<div class="input-group">
<input type="search" placeholder="Search...">
<button type="submit">Submit</button>
</div>
</div>
</body>
</html>
I think you could maybe prevent this by using the same like described here:
https://stackoverflow.com/a/7771215/1501847
For a web/html app running inside iOS Safari you want something like
document.ontouchmove = function(event){
event.preventDefault();
}

iPad sometimes rubberbands with -webkit-overflow-scrolling: touch

Take this markup, stick it in an html file, and view it in mobile Safari on an iPad. I'm using an iPad Mini 4 on iOS 9.3.2.
<html lang="en">
<head>
<title>long</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
</head>
<body style="background-color: #112FCB">
<div id="viewport" style="height: 928px; width: 768px; margin-top: 0px; display: block;">
<div style="width: 638.3376623376623px; height: 771.3246753246754px; transform: scale(1.203125, 1.203125); background-position-x: 0px;">
<div class="page-container" style="width: 100%; height: 100%; overflow-y: scroll; overflow-x: hidden; -webkit-overflow-scrolling: touch; position: relative;">
<div class="page-scroll" style="height: 10202px; width: 640px; left: 0px; top: 0px;">
<div style="position: absolute; left: 254px; top: 259px; width: 88px; height: 89px; display: block; background-color: rgb(255, 255, 255);">
<span style="top:-3px;left:0px;">1</span>
</div>
<div style="position: absolute; left: 252px; top: 1098px; width: 113px; height: 60px; display: block; overflow: visible; background-color: rgb(255, 255, 255);">`
<span style="top:-3px;left:0px;">2</span>
</div>
<div style="position: absolute; left: 229px; top: 1821px; width: 88px; height: 89px; display: block; overflow: visible; background-color: rgb(255, 255, 255);">
<span style="top:-3px;left:0px;">3</span>
</div>
<div style="position: absolute; left: 253px; top: 2503px; width: 88px; height: 89px; display: block; overflow: visible; background-color: rgb(255, 255, 255);">
<span style="top:-3px;left:0px;">4</span>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
So basically we have 4 absolutely positioned divs for showing where you are on the page, inside a very tall div (.page-scroll), which is inside a relatively positioned div with overflow-y: scroll and -webkit-overflow-scrolling: touch (.page-container). The other parent divs (page-viewport and viewport) are there to ensure a consistent look across devices.
On every other device we've tried, swiping to scroll scrolls the page-scroll div inside the page-container div as expected. However, on iPad, we are seeing non-deterministic behavior. If you swipe quickly, the page scrolls normally, but if you swipe slowly, the page will sometimes rubberband. It's as if the touchstart event is getting sent to one of the parent divs, and so the iPad thinks it is at the bottom or top of the page.
However! If -webkit-overflow-scrolling: touch is removed from the .page-container div, the problem disappears. But you lose momentum scrolling, which sucks. I should also note that if this markup is loaded onto a page via an iframe, the problem goes away, but that is not really an option for us (because reasons).
I have tried the suggestion in this similar question to put yet another div inside .page-scroll and set height: calc(100% + 1px), but that did not fix the bug.
I do see a lot of related questions that indicate -webkit-overflow-scrolling: touch has a myriad of problems, but none of those questions are quite exactly this bug, I think.
Has anyone encountered this before? Any suggestions for workarounds?

Making DIV in an IFRAME scrollable

Page A has an iframe (that loads Page B). That Page B has a div#OutputDiv. My goal is to make that div in that iframe scrollable.
SOLUTION (CREDIT TO STEVE!):
Include overflow: auto for that div. However you must specify height too. Simply give any fixed value. eg height: 0.
Use a javascript function to make the div's height always same as the window's, even after window resize. height is now not fixed.
Code:
#outputDiv {
font-size: 12px;
font-family: Arial;
margin-right: 1em;
overflow: auto;
overflow-x: hidden; (optional)
-webkit-overflow-scrolling: touch; (enable smooth scrolling on mobile)
height: 0; (omit-able)
}
$(window).resize(function(){
$("#outputDiv").css("height",0).css("height",$(this).height());
});
$(window).trigger("resize");
TL;DR Full story
Page A.html - has an iframe to load Page B. When on Page A, that div#OutputDiv in that iframe must be scrollable. Works fine on PC but not scrollable on iPad/Android. Page structure:
Page B.php - Left half div#OutputDiv, right half div#map-canvas containing Google Maps.
(Sidenote: I think the #map-canvas CSS is pretty unchangeable, for example changing something may cause the Maps to extend height beyond browser height, which is not what I want.)
Page A.html
<style type="text/css">
#title-banner {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
#real-time-alert {
margin-top: 155px;
margin-left: 10px;
}
.tab-content {
border-left: 1px solid #ddd;
padding: 10px;
height: 100%;
}
#map {
height: 100%;
}
.nav-tabs {
margin-bottom: 0;
}
#panel {
position: fixed;
top: 120px;
right: 10px;
bottom: 10px;
left: 350px;
}
iframe {
width: 100%;
height: 100%;
}
</style>
<body>
<div id="title-banner" class="well"><h1>Real-time incident updates</h1></div>
<div id="real-time-alert">
DEMO:<br>
<a id="demolink" style="cursor: pointer; font-weight: bold;">22/11/2013, 0.32.18AM: 3.128268, 101.650656<br></a>
</div>
<div id="panel">
<ul class="nav nav-tabs" id="myTab">
<li class="active"><a data-toggle="tab" href="#map">Map</a></li>
<li><a data-toggle="tab" href="#message">Messages</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="map"><iframe seamless name="map-report"></iframe></div>
<div class="tab-pane" id="message"></div>
</div>
</div>
</body>
Page B.php
*for div#map-canvas, I had to do the code below, or else when I hover on the page, div#OutputDiv will disappear. This may be not important.
$("*").hover(function(){
$("#map-canvas").css("position","fixed"); });
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map-canvas {
height: 100%;
width: 50%;
}
#content-pane {
float:left;
width:48%;
padding-left: 2%;
}
#outputDiv {
font-size: 12px;
font-family: Arial;
margin-right: 1em;
}
</style>
<body>
<div id="content-pane">
<div class='well well-small' id="inputs" style="margin: 1em 1em 0 0">
<b>TESTING ONLY</b> <br>
<label for="originLat">Incident Site: </label><input type="text" id="originLat" style="width:6em;" />
<input type="text" id="originLng" style="width:6em;" />
<button type="button">Calculate distances</button>
</br>eg. 3.126547,101.657825
</div>
<div id="outputDiv"></div>
</div>
<div id="map-canvas" style="position: fixed; right: 1px;"></div>
</body>
I can't see any overflow controls specified in the CSS (apologies if I missed them).
Have you tried:
div#OutputDiv { overflow: auto; height: 200px; }
The height is just for testing purposes - but you could use Javascript to get the actual height and apply it using either raw javascript or jQuery.
A good example (including how to detect orientation changes if device goes portrait to landscape or similar) can be found on:
How do I get the new dimensions of an element *after* it resizes due to a screen orientation change?

Resources