With Safari on iOS, videos that are embedded below the fold inside of a scrollable iFrame will not begin playing when tapped. If you tap on the video multiple times, or do a long tap, the video may or may not begin playing. On the contrary, the video will play without issue as long as the video is embedded above the fold.
Here is an example showing a video not working when embedded below
the fold inside of an iframe:
https://d1wlensemu2d8.cloudfront.net/safari-bug/example.html
Here is an example showing a video working when embedded above the
fold inside of an iframe:
https://d1wlensemu2d8.cloudfront.net/safari-bug/example2.html
Here are the contents of the iframe from the first example. The video
plays fine when the content is accessed directly:
https://d1wlensemu2d8.cloudfront.net/safari-bug/iframe.html
Until the bug is resolved, one possible work-around may be to extend the height of the iFrame and make its container scrollable. However, this is less than ideal when the content is variably sized and/or contains links to other similarly hosted pages. Can anyone recommend a better solution?
This was tested on iOS 15.4 with an iPhone 12 and iPad Pro (9.7-inch).
Here is a reasonable work-around for the time being:
window.addEventListener('touchstart', function(e) {
e.preventDefault();
});
I've been trying to work this out for a while but I keep coming to a dead end.
Scenario:
I have a youtube video embedded in an iframe on my page.
I am able to play the video just fine on my Mac when using voiceover however on my iPhone 6 and an iPad, when I use VoiceOver and the swipe gestures to move through the page and attempt to play the video, the viewport scrolls to the top of the page when focus reaches VoiceOver.
Here is a gif that is currently happening.
Incidentally, this problem doesn't occur when the youtube video is one of the first items on the page, it only happens when the video is below the fold as it were. The current has JS to make the heigh of all the divs the same.
I should mention I have seen this previous question and indeed attempted to implement it but the issue was still occurring.
Any help or advice would be appreciated.
Load this page on an iPhone, you will see a video player with a cog icon on the control bar. Directly touching this button will not register anything, but if you touch a bit outside to the right, it will fire a hover event. The popup radio list is not selectable either.
All of these work on an iPad. Any idea why?
Well I found out that the <video> element on iPhone Safari will block all touch events. The workaround I use is to reduce its dimension to 1px*1px and always show the poster image, giving the illusion of an actual video. Youtube employs the same workaround.
P/S: the link above may change over time.
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.
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.