iOS scrolling problems in embedded website with iframe - html

I am having a problem with iframes on iOS (Safari).
We're using a webpage within our webpage through an iframe - it looks great on PC & on Android, but on iOS the whole view is broken and I can't get the scrollable iframe to work on iOS anymore.
We used to fix the iOS scroll issue outside of the iframe itself (in a div) with:
overflow: auto;
-webkit-overflow-scrolling: touch;
position: fixed;
Unfortunately, this isn't working anymore so we took it out.
This is how the iframe looks right now:
<div class="nobottommargin">
<p><iframe style="height: 500px; width: 100%; border: none; top: 0; left: 0;" src="https://url.com" scrolling="yes" allowfullscreen="yes" width="320" height="240"></iframe></p>
</div>
Any idea on how to fix this issue or what other alternatives could be used here?
Edit: what I also tried, without any success:
touch-action: auto on the iframe tag
scrolling="no" on the iframe tag
pointer-events: none
Edit 2: Scrolling is working now BUT while scrolling down, it's cutting my iframe off in the middle. Issue only on iOS again (looks fine on Android & PC).
Here's the working iOS scrolling code with the iframe crop bug that I have:
<div class="scroll-container scroll-ios" style="height:500px;width: 100%; position:relative">
<div class="mainContainer-scroll" style="position:absolute;height:100%;width:100%;min-width:50%;min-height:50%;max-height:500%;top:0;left:0;-webkit-overflow-scrolling: touch !important;overflow-y:scroll !important">
<iframe id="iframe_test" src="url.com" style="height: 100%; width:100%;min-width:100%;" name="myiFrameFix" allowfullscreen="yes" scrolling="yes"> </iframe>
</div>
</div>
Edit 3: What I also tried was, removing all the CSS that tricks the browser into using the GPU:
-webkit-transform: translateZ(0px);
-webkit-transform: translate3d(0,0,0);
-webkit-perspective: 1000;
This didn't fix the iframe iOS bug either unfortunately (tried with iOS 9 & 11).
Edit 4: Tried to fix the iframe cropping issue with a script, to make the height of the iframe the same as the whole body. Once again, I was unsuccessful.
<script>
$(function() {
var iframe = $("#iframe_test");
iframe.load(function() {
$("body").height(iframe.height());
});
});
</script>

Check this on your iPhone the scroll works smoothly.
.nobottommargin {
width: 500px;
height: 500px;
-webkit-overflow-scrolling: touch;
overflow-y: scroll;
}
iframe {
height: 100%;
width: 100%;
border: none;
display: block;
}
<div class="nobottommargin">
<iframe src="http://www.weather.gov/" frameborder="0">
</iframe>
</div>

It might be worth including some external JavaScript with a media query to fix this issue, it's currently being applied to every single display.

To fix this. You need to specifically set height on the iframe.
.wrapper {
-webkit-overflow-scrolling: touch;
}
<div class="wrapper">
<iframe
style="height: 500px"
></iframe>
</div>
The hardest part is to get content height of the iframe. You can let iframe tell the parent page by using window.postMessage if you own the iframe. Otherwise you need to check height periodically until you think it is fixed.
var iframe = document.querySelector('iframe');
var setHeight = function(height) {
iframe.style.height = height + 'px';
};
var getHeight = function() {
return iframe.getRootNode().body.scrollHeight;
};
var prevHeight = 0;
var adjustHeight = function() {
var height = getHeight();
if (prevHeight !== height) {
prevHeight = height;
setTimeout(adjustHeight, 2000);
} else {
setHeight(height);
}
};
setTimeout(adjustHeight, 2000);

I've been having this issue for some time now and finally found a fix that works for me by reducing the width of the div disappearing in the iframe. Mine was 100% and reducing to 95% solved it. I'm not sure about the actual max width in px but I think it has to be less than the width of the screen. I tried all the css tricks you mentioned and more, but this is the only thing that has worked.

Related

Responsive iFrame

i'm struggling to get a responsive iframe but so far nothing..
I use the following css and html.thanks in advance.
.testme_container {
position: relative;
height: 0;
overflow: hidden;
}
.testme_container-16x9 {
padding-bottom: 56.25%;
}
.testme_container-4x3 {
padding-bottom: 75%;
}
.testme_container iframe {
position: absolute;
top:0;
left: 0;
width: 100%;
height: 100%;
}
<div class="testme_container">
<iframe src="http://www.gmail.com" allowfullscreen></iframe>
</div>
Could you try to explain in detail what you want to achieve?
I tried your code and judging by the names of your CSS classes (16x9, 4x3) it seems to work fine, however, you will have to use a different URL to test it:
<div class="testme_container testme_container-4x3">
<iframe src="http://www.w3schools.com/" allowfullscreen></iframe>
</div>
DEMO
The reason www.gmail.com doesn't show up is, because Google doesn't allow it to be displayed in an iframe. If you look at the jsfiddle you can see, I did not change anything about your code but the link and I added the class "testme_container-4x3".
This JavaScript function relies on jQuery to make all iframes on the page responsive. It handles video embeds to preserve their aspect ratio without extra vertical or horizontal margin but you need to determine the aspect ratio you'll be using in your embedded video.
https://gist.github.com/dylanvalade/b2ba4eaa99ae7968cfd8
You can actually do this in native javascript without any need to rely on jQuery or other framework/library. Responsive Iframes would work perfectly for this.

Issues with touch scroll on iOS when focusing inputs

I am having some issues with a scrollable div on iOS. When trying to scroll by touching outside an input, it scrolls ok without any problem but when I try to scroll and I touch an input to start scrolling (there are a lot of chances that it happens because it is a div with a lot of inputs) it scrolls the whole window instead scrolling the div. I don't have that problem either in desktop or Android. I found a similar question (iOS HTML Input Tag Stops Scrolling in Scrollable Element) but it doesn't have any answer either. While I don't find any good solution, I decided to prevent the event touchmove when the user touches an input, but it is not exactly what I want.
Maybe someone already faced this problem and can help. I would really appreciate it, thanks in advance.
To get native momentum scrolling on iOS 5+, you'll need:
div {
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
Source: Overflow
Maybe you also need:
div > * {
-webkit-transform: translateZ(0px);
}
Source: Similar question in Stack Overflow
Source 2: Another similar question
This stuff made me crazy too, after testing everything, I found the following answer from Thomas Bachem here working and made it simpler in jquery.
Just add a class scrollFix to the inputs and you are ready to go. (or directly apply that js to any inputs/textarea using$('input, textarea')
Now when you touch and scroll on an input on iOS 8+, the input get all its "pointer-events" disabled (including the problematic behavior). Those "pointer-events" are enabled when we detect a simple touch.
$('.scrollFix').css("pointer-events","none");
$('body').on('touchstart', function(e) {
$('.scrollFix').css("pointer-events","auto");
});
$('body').on('touchmove', function(e) {
$('.scrollFix').css("pointer-events","none");
});
$('body').on('touchend', function(e) {
setTimeout(function() {
$('.scrollFix').css("pointer-events", "none");
},0);
});
Hacky workaround, but by doing this I was able to make scrolling work even on form inputs. The JS forces a reflow in the rendering engine, which is where the bug in iOS8 Safari lies. Changing the height to auto also improved scrolling when focused on a form element, since scrolling is forcibly handled by the browser when focused.
Markup:
<div class="modal-backdrop-container">
<div class="modal-backdrop">
<div class="modal> <!-- Content --> </div>
</div>
</div>
CSS:
.modal-backdrop-container {
z-index: 10;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
height: 100%;
}
.modal-backdrop {
z-index: 10;
height: 100%;
background-color: rgba(255,255,255,0.5);
overflow: auto;
overflow-x: hidden;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.modal {
position: relative;
width: 400px;
max-width: 100%;
margin: auto;
background-color: white;
}
JS:
// reflow when changing input focus
$modalInputs = $('.modal').find(':input');
modalInputs.on('focus', function() {
var offsetHeight = modal.$backdrop[0].offsetHeight;
modal.$backdropContainer.css({
'height': 'auto'
});
});
modalInputs.on('blur', function() {
var offsetHeight = modal.$backdrop[0].offsetHeight;
modal.$backdropContainer.css({
'height': ''
});
});
Not sure of the var offsetHeight = modal.$backdrop[0].offsetHeight; line is needed, since both this and changing the height value should force a reflow.

Google maps with jquery.mobile: how to correctly resize map canvas?

I am writing a jquery mobile app which needs a map.
For the map I am planning to use Google maps service.
To account for orientation changes, I tried to use something like:
<script>
$('#page-map').live('pagecreate', function(event) {
var map = $('#map_canvas').gmap({
...
});
...
$(window).resize(function() {
$('#map_canvas').width($(window).width());
$('#map_canvas').height($(window).height());
});
)};
</script>
The problem: this code correctly resizes the map canvas when the device is rotated, but it looks like jquery mobile resize() is skipped (the url bar is visible, for example...).
Not even adding to the "resize(function() {" code something like this:
google.maps.event.trigger(map, 'resize');
is of any help.
UPDATE:
The issue only happens on the only mobile device I'm testing my pages - a Samsung Galaxy Mini (GT-S5570), Android 2.3.4 (Gingerbread). It does not happen when resizing window on a desktop PC (i.e: on a desktop browser map_canvas is correctly filled when browser's window is enlarged, even without the resize() binding, only due to width/height at 100% on map_canvas...)
I assign a size through css to my map in jquery mobile
I add the map_canvas inside div with dimencion deuin want in this case 100%
CSS
#map_content {
padding: 0px;
width: 100%;
height: 100%;
overflow: hidden;}
#map_canvas {
width: 100%;
height: 100%;
padding: 0;
text-shadow: none;}
HTML
<div data-role="content" id="map_content" data-theme="a">
<div id="map_content">
<div id="map_canvas"></div>
</div>
</div>
I've tried the above answer (plus many others) and nothing worked for me. Actually, the above code was working for me, but just until I started using jQuery Mobile. Somehow, when I load jQuery Mobile (funnily enough, I noticed that it's the JS, no the CSS) the map_canvas has no height (a trick to check the height of the element is adding a border to it like border: 1px solid red;).
Eventually, I managed to solve the auto-resize when the orientation changes by using the following code/css:
<div data-role="page" id="pageID">
<div role="main" class="ui-content">
<div id="map_canvas">
</div>
</div>
</div>
And in the css:
html,
body,
#pageID {
height: 100%;
margin: 0;
padding: 0;
}
.ui-content {
padding: 0;
}
.ui-content,
.ui-content #map_canvas {
height: inherit; /* the trick */
}
So, basically the: height: inherit; solved the problem for me.
Credits: https://jqmtricks.wordpress.com/2014/12/01/content-div-height-css-solution/comment-page-1/#comment-250
I hope it helps!

PhoneGap/Cordova: Prevent horizontal scrolling

I have an app built on Cordova and on some of my pages I am able to scroll horizontally out of my content into white space.
This is weird as I have nothing there that extends beyond my #wrapper, which is set to width: 100%.
So I was wondering if there was a way I could disable horizontal scrolling in the app altogether?
UPDATE:
Code on page as requested:
body {
background-color: #fff;
font-family:Arial, Helvetica, sans-serif;
color: #b7b8b9;
height: 100%;
width: 100%;
}
iframe{
border: none;
width: 100%;
/*margin-top: 50px;*/
}
#header{
height: 50px;
width: 100%;
}
<body>
<div id="wrapper">
<div id="header">
<div class="headerback">Home</div>
<div class="headerrefresh"><script>var pathname = window.location.pathname;</script><script>document.write('Refresh')</script></div>
<div class="headertitle"><h2>Get the Look</h2></div>
</div><!--HEADER-->
<iframe src="http://www.mbff.com.au/getthelook"></iframe>
</div>
</body>
Try to debug your page in Chrome (webkit) with the exact dimensions of your device. This solves most rendering issues for me.
I do not know the specific issue here, but it looks like one of your elements is flowing outside of the wrapper. You could for example try this in your css:
div.wrapper { overflow: hidden; width: inherit; }
Although it might be a better idea to find out why your page is expanding horizontally?
I was looking for the solution to this problem for a long time.
Finally I solved it in the following way.
I set style for bodyand html tags:
position: fixed;
width: 100%;
height: 100%;
overflow: hidden;
After that I've added div to body and set the style for it:
overflow-y: auto;
height: 100%;
So, I have got fixed body, which contains div with vertical scroll bar.
// Phone Gap disable only horizontal scrolling in Android.
// Add this code in your Phone Gap Main Activity.Initially Declare the variable
private float m_downX;
//Then add this code after loadUrl
this.appView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
// save the x
m_downX = event.getX();
}
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
// set x so that it doesn't move
event.setLocation(m_downX, event.getY());
}
break;
}
return false;
}
});
Try adding the following code to your .html file:
document.body.addEventListener('touchmove', function(event) {
event.preventDefault();
}, false);
For the sake of completeness, I thought the answer which makes use of the official method of doing such a thing via the preference tag should be added:
<preference name="DisallowOverscroll" value="true"/>
Supported by Android and iOS according the documentation.
Default: false
Set to true if you don't want the interface to display any feedback when users scroll past the beginning or end of content. On iOS, overscroll gestures cause content to bounce back to its original position. on Android, they produce a more subtle glowing effect along the top or bottom edge of the content.
In my case it was broken styling like below
<body>
<div style="margin-left:5%; width:100%">Content</div>
</body>
which cause div to became horizontally bigger than body. I could see scroll when app run in browser. Set width to 90% (as it was initially intended) fixed the problem.
Generally, as it already pointed out here, enough to find element with wrong style which makes your page expanding horizontally and fix it.
BTW DisallowOverscroll was not helpful in above case.

Fill window with iFrame and not show scrollbars?

How can I make my iframe fill the window and not display any scrollbars?
This works for IE6, I would like to get it to work for all browsers if possible:
<iframe name=iframe1 src="theSiteToShow.html" width="100%" height="100%" frameborder="0" marginheight="10" marginwidth="10"></iframe>
<script type="text/javascript">
function resizeIframe() {
var height = document.documentElement.clientHeight;
height -= document.getElementById('frame').offsetTop;
// not sure how to get this dynamically
height -= 20; /* whatever you set your body bottom margin/padding to be */
document.getElementById('frame').style.height = height +"px";
};
document.getElementById('frame').onload = resizeIframe;
window.onresize = resizeIframe;
</script>
You should be able to do this using CSS only, without any need for javascript. The following works for me in IE6+, Google Chrome and Safari:
<style type="text/css">
body {
margin: 0;
overflow: hidden;
}
#iframe1 {
position:absolute;
left: 0px;
width: 100%;
top: 0px;
height: 100%;
}
</style>
<iframe id="iframe1" name="iframe1" frameborder="0"
src="theSiteToShow.html"></iframe>
Your frame margins should be set in the body of theSiteToShow.html.
UPDATE
Following your comment, I used the following as a test page:
<html>
<head>
<style type="text/css">
body {
margin: 0;
overflow: hidden;
}
#iframe1 {
position:absolute;
left: 0px;
width: 100%;
top: 0px;
height: 100%;
}
</style>
</head>
<body>
<iframe id="iframe1" src="http://stackoverflow.com" frameborder="0"></iframe>
</body>
</html>
Tested in IE6+, Chrome, Safari and Firefox, it works just fine and fills the entire window.
I was having the same issues with the scroll bars as well as the No Context Menu showing up, even though all these elements had been disabled. After a few days of trying to solve them, I stumbled on this post, which helped a bit, but led me onto finding a post on flexible webplayers with three code examples. Here're the links:
http://virtualplayground.d2.pl/?p=367#comment-224
Download package
Use the index file if you want a blank sheet to work from, replace your existing code in your exported .html file (from Unity export), replace the 'unityObject.embedUnity' link with your own link to your .html file located on your server.
To embed the player in your page using an iframe add:
Lock and load.
Hope this helps.
^_^