iPad Safari mobile seems to ignore z-indexing position for html5 video elements - ipad

I got a video element on a page that's working fine both in safari mobile and desktop.
I have a seme-transparent pull-down menu that's working fine. The problem is, when the menu is over the video element, on the desktop safari i can see the video under the menu (as desired), while on the mobile version the video element stay on the foreground (ugly) no matter what i tell the css. Is there any workaround?

The issue only occurs if the video element was dynamically created. If the element was just in the page as it loaded, z-index works fine.
You can fix z-index on dynamically created videos by giving the video element -webkit-transform-style: preserve-3d.
Yep, it's as bad as haslayout on IE!

Unfortunately not.
Based on my experience and understanding of how iOS currently works, this isn't possible.
Mobile Safari on the iPad cuts a hole for a Quicktime window , which plays back the video using the built in hardware acceleration to improve battery life. (The iPhone and iPod Touch just open it up in a separate window to achieve the same effect.)
This window doesn't play nicely with the other HTML on the page. In fact, I haven't found a way to get mobile Safari to display anything on top of a tag. My guess is that this is because the hardware acceleration only allows for video scaling and positioning, and that it's only able to handle one video at a time.

I'm using flowplayer and a simple CSS dropdown menu and had the same problem.
I have drop down menu that, when tapped, covers part of the video area. The submenu shows up over the video as expected, but no touch events were being sent.
I fixed it by combining a couple of suggestions from others answering this question: I set visibility:hidden when opening the menu and visibility:visible when closing the submenu, AND set the -webkit-transform-style:preserve-3d CSS property on the video.
Here's the pertinent code. I left out the CSS for the menubar, but it does what you might expect - resulting in a menu that covers portions of the video.
menu and video HTML
<div id='nav'>
<ul>
... <!-- bunch of ul/li stuff here for the menu and submenus -->
</ul>
</div>
<div id='videoplayer'><!-- for flowplayer --></div>
CSS
video {
-webkit-transform-style: preserve-3d;
}
Javascript
$(document).ready(function(){
$("#nav li").hover(
function() {
$(this).find('ul:first').css({visibility: "visible",display: "none"}).fadeIn(300);
$("video").css({visibility:"hidden"});
},
function(){
$(this).find('ul:first').css({visibility: "hidden"});
$("video").css({visibility:"visible"});
}
);
);

I have managed to place a menu div over a html5 video tag in mobile-safari on the ipad. To be honest I didn't have any problems and it just worked. It could be though because I was using CSS3 animations and therefore the GPU? You could try using a hack to add an element to the GPU. If you put -webkit-transform: translateZ(0); on the element it should force it to use the GPU...

When you have an element you want to be in front of your <video> in Safari, you need to set into that element the transform: translateZ(1px) or more pixels, as Safari is setting to your <video> element a 0 value for Z axis (transform: translateZ(0)).
This is the only thing it worked to me. No z-index, no transform-style:preserve-3d.

I ran into this also. The only thing that I could get to work for me was to add
display:none
to the video tag when showing a div over it that needed to be clicked on.

-webkit-transform-style:preserve-3d and -webkit-transform:translateZ(0) didn't work for me.
Using Flowplayer with the ipad plugin and the controlbar plugin allowed me to remove the ipad created control bar and replace it with something that can be z-indexed below my modal windows.

You can fix z-index on dynamically created videos by giving the video element -webkit-transform-style: preserve-3d.
This worked for me with a dynamically created video element. I also set the z-index of the over-laying div to z-index: 888; which may also have helped.

I had this problem which was occurring on mobile devices with an off canvas menu. When the menu was over the video you could not tap any of the menu items.
I fixed it my moving the video somewhere else when the menu was on by positioning it absolutely at -100000px when the menu was not displayed it set it back being positioned relatively.
I found using display none did not work as when you set it to block again the video would not work.
I also tried setting the height to 0 - this did not work as the video still seemed to take up the space even though you couldn't see it.
The final method seems a bit extreme but it is not really noticeable when it is being used.

This is the code that will work on both the iPad and iPhone. I tried removing the controls and then add them again, but this worked only on iPad not on iPhone. After remove the opacity and then add it again it worked on iPhone also.
$("#overlay_open").click(function(){
$("video").prop("controls", false);
$("video").css("opacity", 0);
});
$("#overlay_close").click(function(){
$("video").prop("controls", true);
$("video").css("opacity", 1);
});

Just ran into this issue today & had to cobble together a solution from multiple answers since none fully handled the problem ...
I have video elements in a collapsed "table view" style list that were capturing touch events on iPhone when trying to tap on other list items. On iPhone the videos would play when tapping other collapsed elements that happened to be occupying the same spot on screen.
Fixing this required all of the following:
1) Using this:
video{
-webkit-transform-style: preserve-3d;
}
... didn't seem to have any effect, but I left it in anyway. Everything's working now so I don't want to screw with it further :)
2) Toggling visibility: hidden alone didn't work, and display:none didn't work as expected.
3) In addition to "visibility" the HTML5 video tag controls attribute also has to be added/removed dynamically. Either:
$("video").css({visibility:"hidden"}).removeAttr("controls"); or $("video").css({visibility:"visible"}).attr("controls", "controls");
4) Must set visibility/controls on document load based on initial browser/screen size
5) Although the main concern was the screwy iPhone behavior, I also had to account for responsive window size changes above my smallest media query breakpoint of 600px - otherwise the videos would appear/disappear at the wrong screen sizes.
$(window).resize(function(){
if ($(window).width() > 600){
$("video").css({visibility:"visible"}).attr("controls", "controls");
}
});
Quite a pain to work around what's essentially a stupid mobile Safari bug... I sure hope it works on iPad when I test it later...

For anyone running into issues with this still, another fix that ended up working for me was to change the options in the embed code to not allow controls, suggested videos, and video title and player options. I added a simple Modernizr.MQ query to change the src for tablet and mobile, and included the following to the iframe src for mobile:
?rel=0&controls=0&showinfo=0
I never completely tracked down why this works, but my guess is that the controls have some user-agent style that gives them a high z-index and makes the element sit on top of everything.

Related

Embedded YouTube videos don't play on iPad (iOS 7) while HTML5 search input is visible

This is a bug that I have managed to fix by brute force, but I don't understand why the solution worked.
The problem was that embedded YouTube videos weren't working on a particular (responsive) site on iPad (tested in iOS7) in landscape view. I managed to narrow it down to a particular CSS rule that was showing a search input in the header when the browser was wide enough, so it would show in an iPad's landscape view but not in its portrait view.
After a little more brute force fiddling, I found that removing the type="search" from the input tag (which causes it to fall back to the default type="text") would fix the problem. None of my searches have come up with an explanation for why this works though, or even anyone else experiencing the same thing.
Some more details on the bug
The site works by showing an image at first, which would be replaced via JavaScript with the YouTube iframe when clicked. After this first click, it would autoplay on desktop browsers, and on the iPad it would load the video but wouldn't play until the user presses it again.
If the type="search" input was visible (display: block;), then tapping on the embedded video would not cause it to play; there would be no visible response to the tap. If I zoomed in and tapped on the controls at the top, like the name of the video, I could see them being underlined, and testing showed that there was no element covering the iframe and intercepting events.
Strangely, tapping on the very edge of the right hand side of the iframe would cause the video to start playing correctly. Otherwise, changing the iPad to portrait view (causing the search input to be hidden via CSS) would enable the iframe to be clicked in order to start the video playing. After that first click, all the video controls would work regardless of whether or not the search input was showing.
Just experienced this first-hand myself and wanted to add my kudos for you having written this up. Your SO question, even without an answer, pointed me in the right direction.
In my case it was nothing to do with Youtube. I had a page generated by Drupal in a large-ish site, in which the site-wide search mechanism used an auto-complete drupal module which had type="search" as the main input's type.
In IOS, users reported that Facebook, Twitter and Google Plus's respective "like" buttons all didn't work, along with a much larger angular app embedded in the page. They all used iframes and none of them seemed to respond to clicks.
Changing this seemingly innocuous, unrelated input's type from search to text solved this problem immediately.
Baffling.

ipad youtube embed, blocks touches on lower z-index

On iPad I've been experiencing an issue where lower z-index items can not receive touch events.
The cause of that there is a <video> tag within the iframe which blocks interaction with lower z-index elements. All my usual fixes for ipad force-redraw has messed up the embed in some way. Either :
the video either plays audio only
or the entire iframe is not clickable.
Here is a fiddle: http://jsfiddle.net/krismeister/KynXG/3/
Setting 'controls':0 will fix this issue, but there is no JS interface to re-activate the controls, once the video has started.
edit:
I found this issue in the yt-data bug tracker. Please vote it up.

VideoJS: Videosize on an iPad

I am using VideoJS to show a video. It works great in all browsers on each and every system. Exception is the iPad (iOS 5 and iOS 6, both tested on Safari and Chrome). The video resizes to about 300px width.
When i delete videoJS from the page, the video is shown correctly. But i need videoJS for skinning purposes and because it makes HTML5 video work in jQuery sliders.
I tried several things:
Manually entering width and height in video.js or JS.
Adding CSS (including !important) to the videotag and even all tags (param) below.
Tried some vague techniques i found on stackoverflow. Like -webkit-transform-style: preserve-3d; in the video-tag.
Tried to play with wmode.
Nothing seems to work. Does anyone have an idea?
First, if you haven't yet, you may want to upgrade to v4.0, released at the beginning of May (2013).
With 4.0, you can see a few examples of setting the width height, that are at least working for me on my iPad:
Width/Height 100%: http://jsbin.com/uyelud/1/edit
Width 200px/900px (weird dimension for example) http://jsbin.com/ojajuc/2/edit
To walk you through the vjs code...
The width height settings are grabbed from the tag here:
https://github.com/videojs/video.js/blob/v4.0.3/src/js/player.js#L112
Removed from the video tag (because it's wrapped by a container div and made to fill the container)
https://github.com/videojs/video.js/blob/v4.0.3/src/js/player.js#L144
Applied to the container div
https://github.com/videojs/video.js/blob/v4.0.3/src/js/player.js#L180
And then handled by the UI component code
https://github.com/videojs/video.js/blob/v4.0.3/src/js/component.js#L647
If you have different results on your page, you may want to set up a reduced test case to help narrow it down.

slow list view scrolling on iPad when scrolling in an overflow:auto div

I am developing a Phonegap app for the major os platforms and am currently testing it on an iPad with iOS 5. Im using jquery mobile. So for large screens i've used the splitview jquery mobile plugin. http://asyraf9.github.com/jquery-mobile/
I've put a
$scrollArea.css('overflow-y','auto');
$scrollArea.css('-webkit-overflow-scrolling','touch');
to make the page scroll instead of using iscroll like the plugin was using. Now whats happening, is that the page isn't loading/repainting as the user scrolls. I have a list of 100 items and i scroll through them. The scrolling itself isn't slow, but it takes almost a full second for the new list view rows to pop into view after it has been scrolled. Before that it's a blank area.
On observing, i can see that the the list items don't pop into view until the scrolling has come to a halt. (momentum scroll)
A similar issue is here http://forum.jquery.com/topic/help-with-slow-list-view-scrolling-on-ipad-when-scrolling-in-an-overflow-auto-div
What can i do to make this work normally?? The same thing works fine on android tabs. pls help.
EDIT: If i use only
$scrollArea.css('overflow-y','auto');
then i dont face this issue of momentary blank areas after scrolling, but then the scrolling is painfully slow.
Please don't suggest using iScroll. Already tried that. its much much slower that what i get with -webkit-overflow-scrolling, and i cant use it.
My Approach
So, I tried a lot and I read even more about this problem. I ended up with a solution which is "OK" to me (because it works), but which is definitely not near to "perfect".
When using this CSS:
.container {
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
you run into a lot of problems when having a complex design (in my case a fullscreen background image), and it gets even worse, when using absolute positioned elements and iframes. (Which is - of course - both the case I needed).
So, what did the trick? Basicly this CSS:
.container > * {
-webkit-transform: translate3d(0,0,0);
}
With this rule the content was almost all the time rendered right away without getting those blank areas. Only when scrolling down the first time very fast it's a little flickering.
But be careful with the rule -webkit-transform: translate3d(0,0,0);. Using this rule heavily on many child elements forced Safari to: sometimes slow down but almost all the time to crash. The best thing is to wrap all content elements into a single div, works fine.
Done? Not really. There is still the iframe-issue: ("argh")
iframe
When the iframe is not fully in the visible part of the container at the start it gets cropped or is not even displayed at all. This could sometimes also occur when scrolling around. So, I tried to force Safari to re-render this part anytime scrolling is completed and came up with this:
//using jQuery
var container = $('#container');
var iframe = $('#iframe');
container.scroll( function (event) {
iframe.css( 'marginLeft', 1 );
setTimeout( function() {
iframe.css ( 'marginLeft', 0 );
}, 1 );
});
The thing with the scroll event on a touch device is, that it's only triggered when the scrolling has come to an end, so this function is not fired at anytime but when the momentum has come to an end. The short movement is actually not visible.
So, maybe this is helpful for somebody.
Further information
Here a few more links on this issue:
On how the scroll event is fired in iOS:
javascript scroll event for iPhone/iPad?
Bug report of this problem to Apple:
https://stackoverflow.com/a/7893031/1456376
iframe example with the same problem:
https://stackoverflow.com/a/8275972/1456376
We have used the plugin below in our project, did you try this one out?
https://github.com/jquery/jquery-mobile/tree/master/experiments/scrollview
On iOS it uses hardware acceleration to render the scrolling. It is rather easy to use, all you have to do is to assign an additional class to your div.
We did have some issues on Android 2 with this plugin, to overcome those issues we changed the scrollMethod property in jquery.mobile.scrollview.js.
I hope it helps you solve your scrolling problem

Scrolling on iPad for an iframe within GWT window

PLEASE NOTE: This is not a "use two fingers to scroll" problem. Whether it is one finger, or two, or three, or the whole hand, for some reason our iframe does not scroll on an iPad. :)
Here is the scenario:
In our web application, which is built using EXT-GWT, we have a few windows that open as (maximized) pop-ups and present some forms to the users. These forms, which are most of the times external, are rendered in an iFrame and some of the forms have their content collapsed at the initial load - the user can choose to expand any section of the form, fill it in and submit. Now everything works fine except the scrolling in iPad. After the iframe's content is loaded and collapsed (collapsing is done using JS on the client side, basically, the content loads as expanded by default and then is collapsed by JS) iPad just fails to provide scolling to the iframe. Even after the content of the iframe is expanded the iframe does not get any scrolling.
As of now, we have solved this problem by increasing the height (using JavaScript) of the EXT-GWT window to the size of the expanded iframe body content. This makes the whole window scrollable, instead of just the iframe within the window. While it works, the window becomes way to big, so I was wondering if there is any better way for us to provide scrolling to the iframe.
Thanks for the help,
Nitin
For iOS devices you need set overflow: auto; or the scrolling won't work. For my web apps I used fancybox to display iframes modally and once I change the overflow setting in the css file the two finger scroll worked perfectly on the iPad.
After trying (almost) everything, I have come to the conclusion that increasing the GWT window height to the iframe.body.height is the only solution for getting the window/iframe to scroll on iPad. Hopefully, this will help someone in future.
I´m pretty new to GWT, but for me it worked like this:
The parent-div of the iframe has a class in my case, x-component.
I made an entry to my css file like this:
.x-component{-webkit-overflow-scrolling: touch; overflow:auto;}
It works as well if I set these entries not to the class, but to the div-element itself.
Hope that helps

Resources