I'm having one of the strangest rendering issues with Android browsers (Galaxy Tab 10.1 and S3 so far .. haven't tested on iPhone or other mobile browsers).
I'm dynamically embedding a fixed position responsive Youtube video on a webpage. You click a button in Javascript - it creates a black backdrop (also fixed position) and a Youtube embed with an id so I can control the properties at different screen sizes. So far so good. This goes off without a hitch. I check it out in Chrome, Firefox and even IE and I'm not disappointed. Yet.
I check it on my Android phone (Galaxy S3 - stock browser) and it appears that the video is having a hard time understanding where it's supposed to be rendered. I notice at least 3 repositions before it settles on a spot. Sometimes I'm lucky to see part of the element is somewhat on screen. Most other times, not so lucky. The code hasn't changed and the browser size definitely hasn't changed; just the rendering has.
To make matters worse, it seems like the element is actually placed in the correct place but rendered incorrectly. If I click on the center (or near enough to it), the video plays! The rendering shows it playing while re-rendering constantly, still unsure of where its supposed to be.
I know this problem sounds super-crazy and it might be a tricky one to even diagnose (let alone debug) so I'm including as much code related to the whole operation as possible. Help is greatly appreciated!
Creating and Embedding the Video
donModal.addEventListener("click", function(e) {
e.preventDefault();
var donPreview = document.createElement("iframe");
donPreview.src = "http://www.youtube.com/embed/oeZgLFsglcc";
donPreview.frameborder = "0";
donPreview.allowfullscreen = "allowfullscreen";
donPreview.id = "donModalVideo";
document.body.appendChild(donPreview);
sfx.toggleBackdrop(donPreview);
});
}
Video Styles
#donModalVideo {
position: fixed;
width: 40%;
height: 50%;
top: 25%;
left: 30%;
z-index: 95;
}
URL for Test
Can't fiddle right now .. hope this is ok ...
http://openheavens.designbymobius.ca/artistes#donmoen
Solved it!!!
There were a combination of factors that contributed to the problem.
There was no height set for it (or it's parent element).
Fixed position is glitchy on mobile devices
Armed with that knowledge, I:
Changed the position property to static.
Wrote a little function to set the height as a fixed ratio of the width (I used 0.5625) which triggered every time the window was resized. Now the video size is flexible and it perfectly maintains its ratio.
Wrote a second function to set the top value as the (viewport height - video height) / 2 + window.pageYOffset. It's triggered whenever you scroll the page.
End result is a static position video which dynamically adjusts width while maintaining its ratio as well as simulates the effect of position: fixed.
The end result can be seen here. Click to watch an artist preview video :)
Related
I used Vue to create my site and desktop version works perfect. When tested on Mobile IOS Safari and Chrome the page jumps up a bit when scrolled to bottom the first time. Android works fine. This problem doesn't happen the second time you scroll to bottom before you refresh the page. This problem also won't happen if you test it on desktop through dev tools.
The site's profile page does not have this problem.
I made a screen recording of the behavior: https://drive.google.com/file/d/1B93xtwF8f2VWAVegLbsZFULn3TymUCNZ/view?usp=sharing
I converted all the vh values to px to prevent browser reflow like so
let vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh',${vh}px);
it fixed my layout but didn't help with the jumping problem.
I also tried to set up a fixed height to the body by assigning CSS height values through Jquery .css method, when the fixed height is taller than the actual content, this problem does not happen.
I'm sorry that I don't have a snippet to reproduce this problem, I have no idea where the problem is at all.
My site url is https://www.jingqi.work
The expected result would be without the jumping up movement when scrolled to bottom, basically like how the profile page behaves.
Page scrolling using the keyboard (PgUp/PgDown, Space) sometimes gets difficult if there are elements with fixed positions at the top of the page, e.g. navigation bars: content that was not visible at the bottom of the viewport might be hidden by the fixed elements after scrolling.
How to address this problem? Do browsers calculate, how far they should scroll? I observed different behaviors for different browsers and also for the same browsers on different pages (for example, Firefox leaves about 80px of old content on http://www.sueddeutsche.de/, but far less on http://www.taz.de. Chromium leaves much more content.).
Is this a problem at all, i.e. does anybody beside me use the keyboard to scroll a web page? Do you know any statistics?
To illustrate the problem, I created a Fiddle:
https://jsfiddle.net/x7hj8c4m/
Try to scroll the content using Space on Firefox. The fixed element will cover text that was not yet visible before scrolling. If you add left: 0, it works.
Very interesting observation.
Firstly, pressing space is equivalent to pressing PgDn. And when PgDn is pressed, the page should scroll vertically by roughly "one page's worth of px". As shown by the OP's fiddle, Firefox in particular calculates this value differently, depending on whether it detects a fixed header.
From my own tests on IE, Chrome, Firefox, I deduced that:
Without a position: fixed element, Chrome and IE scroll down by ~87.5% of the document height; Firefox scrolls down by document height - scrollbar height - ~20px.
With a position: fixed; width: 100% element at the top-left of the screen, Firefox intelligently understands that the element perceptually reduces the document height, and so applies: document height - scrollbar height - fixed element height - ~20px. The condition appears to be quite specific: the element must be fixed exactly at the top-left of the document's box model with full width in order for it to work. The other browsers (Chrome, IE) don't perform such compensation, and performs the standard 87.5% scroll.
I don't know if this is relevant, but it might have something to do with support for position: sticky.
Scrolling by keyboard is a pretty basic behaviour that probably doesn't interact too much (if at all) with the DOM, so expecting it to account for fixed elements is probably too much. There seem to be browser-specific predefined increments (I have no idea if or how they can be customized), but note that the increments are usually smaller (presumably small enough) when you use the up/down arrow keys.
EDIT:
These issues appear to have been fixed by iOS8. Consider this issue an iOS7 and earlier bug.
I've got some content (subject to CORS) that I'm serving in an iframe, that I want to be always stretched across the bottom of the browser window. I need this content to keep the same aspect ratio and fill the entire width of the browser, otherwise things will look weird. Because I don't have access to the iframe's contents I'm using -webkit-transform: scale to properly size everything properly.
I'm calculating the scaleFactor:
width = 600; // this is the original width of the iframe's contents and never changes
scaleFactor = window.innerWidth/width;
Then I set some CSS based on that scaleFactor, whenever window.innerWidth changes size:
$container.css({
'width': (width * scaleFactor) + 'px',
'height': (height * scaleFactor) + 'px',
'padding': 0
});
$iframe.css({
'-webkit-transform': 'scale('+scaleFactor+')',
'transform': 'scale('+scaleFactor+')',
'-webkit-transform-origin': '0 0',
'transform-origin': '0 0'
});
This works perfectly everyplace except iOS where it starts to break down if you zoom in too far. The iFrame starts to drift off the page and isn't near wide enough. I have no clue what's going on here.
Images of what I'm talking about: Good scaling, Bad scaling.
I've got a test page setup here that clearly demonstrates the problem on any iOS.
Anybody have any ideas?
Here's the result of my extensive investigation before I gave up.
There are two major problems involved in applying transform: scale to content inside iframes on iOS. The first was what I pointed out in the original question, that content starts to drift away from it's specified location on the page if you are using fixed position elements. It works up to a point that seems to be based on the original size of the element, the scale factor, and presumably the viewport width. In my tests a large element might scale and position perfectly when scaled at any factor greater than 0.85. A small element might be positioned perfectly so long as the scale factor is at least >3.5. It seems almost random, so I didn't bother determining what the exact point was.
I didn't try this on relatively positioned elements, but I'm assuming they function similar to fixed position elements.
There is a rather kludgy workaround for this involving using absolutely positioned elements anchored to the bottom of the page using scroll offsets and innerHeight. i.e.:
container.css('top', (document.body.scrollTop + window.innerHeight - container.height()) + 'px');
container.css('left', document.body.scrollLeft);
And updating this on every drag, transform, pinch, resize, etc. There is some weirdness involved with this method (iOS doesn't update scroll offsets until after a drag has completely stopped) but it's workable if you absolutely had to do it.
However, even though that's a possibility, when you scale content inside iframes on iOS, if you have ANY anchor tags (or other elements that need to be clicked on), the clickable area stays unscaled. If you have an image in inside an anchor tag that's 200x100 and you scale it 2x, the image will be twice as big, but the anchor will only respond to the first 200x100. Using the iOS simulator, if you double click on an image outside the clickable area Safari is even helpful enough to darken the original bounds so you know where you could have clicked. It's pretty much a deal breaker if you want to display anything other than text/images that don't require clicking or other inputs. More information here:
CSS3 Transform scaling issue on IPad Safari
"-webkit-transform: scale(2)" doesn't affect click area of Facebook Like Button (on iPad)
Until Apple fixes these long standing bugs in mobile Safari, it seems that trying to scale iframe content using webkit-transform isn't a viable option unless you are only targeting Chrome.
Edit:
Demo of scaling issues here.
Combo of iframe, transform scale, and ios is tricky.
There are bugs with transform scale. Not always in your control.
You can try zoom property instead of scale, and use scale for firefox where its not supported.
I don't have ios here so I cant check but it often works wonders. Though you may have issues with line breaks in text with zoom.
zoom solves this bug in chrome
I'm new to programming and I have been using the book "HTML5 for iOS and Android - A Beginner's Guide" (http://html5formobile.com/) to teach me the basics of creating a HTML/JavaScript web page, which is then put into a wrapper supplied with the book, to make the page function as an Android App.
The problem I am having, is that I am trying to align a piece of text to the horizontal center of the screen, purely using JavaScript. The code I have written correctly functions when viewed on my desktop PC with either Chrome or IE, however it does not function correctly once placed in the wrapper and viewed on my phone as an app or as a standalone web page viewed on my phone. Here is the small piece of code I have created to do this:
<script>
instruction_text_element = document.createElement("text");
instruction_text_node = document.createTextNode('This text should be aligned to the horizontal center of the screen.');
instruction_text_element.appendChild(instruction_text_node);
document.body.appendChild(instruction_text_element);
instruction_text_element.style.position = 'absolute';
instruction_text_element.style.left = ((screen.width / 2) - (instruction_text_element.offsetWidth / 2)) + 'px';
</script>
In this code, I calculate the mid point of the screen, then subtract half the width of the text element from this, to create the left position to place the text element, so that an equal amount of white space is seen on either side of the text. As mentioned, this works fine when I view it on my desktop PC with either Chrome or IE. However once it is placed in the app wrapper and viewed on either a real phone or a virtual one on my pc, or indeed when just viewed a plain web page on my phone, the text does not appear in the correct central position - it is appearing too far to the left of the screen, I'd say roughly 25% too far to the left. By this I mean the blank space on each side of the text should be 50/50 but it is showing more like 25/75.
Can anyone tell me why this is happening? I appreciate that my code is perhaps not the best way to go about creating and aligning text, but I am just starting out with programming and learning the basics, and so I wish to know where this PC/mobile discrepancy is arising in my code, so that I can avoid it in the future as I learn more about programming.
Many thanks for any help you can provide!
Cheers!
Updated:
As per emrys57's suggestion, I have tried the following example to see if the phone is getting confused as to its screen width:
<body>
<div id="div_id", style="width: 100px; background:#00CC33; text-align: center;">!</div>
<script>
document.getElementById("div_id").style.position = 'absolute';
document.getElementById("div_id").style.left = (window.innerWidth / 2) + 'px';
</script>
</body>
Again, this works fine on my desktop pc, but on my phone the little green div box is appearing too far to the left of the screen. I tried swapping screen.width out for window.innerWidth but it produces the same results. Swapping it out for window.outerWidth results in the box appearing even more too far to the left.
Does anyone know how to reliably measure the screen on a phone, or is it simply never reliable?
Cheers!
When I tried similar tricks, I found that some phone/browser combinations, particularly older ones, gave strange values for screen size. iOS seems mostly predictable, but Android wasn't. To check this, you could try placing a fixed-size little div with its left hand edge in the centre of the screen,
little_box.style.left = (screen.width / 2) + 'px';
and then measure it with a ruler. If it's not in the middle, you know the phone is confused over the screen size.
I use horizontal sizes in % to overcome this problem. All phones seem to have a good idea of what
width: 50%;
means.
You could more easily align your text in the center by putting it in a div:
<div style="width: 100%; text-align: center;">!</div>
That "!" should appear in the middle of the screen.
I am using the jAlbum program with the Lightflow Skin to create a gallery. Works well but when I attempt to navigate the gallery on my laptop and the images will slowly creep up and the titles will disappear. I cannot replicate this issue on my desktop, however, my screen size is large enough that the max image size does not override the screen size. This happens in Firefox (multiple versions) only. In Chrome and IE it displays correctly. Also the Close X is off to the left a bit too much (In all browsers on laptop only).
It would appear that the script is calculating the top property incorrectly.
Here is a bit of code:
<div id="lightwindow_container" style="height: 469px; width: 532px; left: -266px; top: -235px; display: block; visibility: visible;">
For the photos that go off the page if I change the top property I can make it fit the page without issue. (By changing it in Firebug when looking at the page.)
Here is a screenshot showing the issue:
Here are the page(s) in question.
How do I check and see if this is a script error or simply a local browser issue and how do I fix it if it is a script error?
Note: I would add the code but there is so much code it will reach the max limit allowed here in SO.