JavaScript to hide browser chrome causes position: fixed bug on iOS - css

Here is my site:
http://smartpeopletalkfast.co.uk/pos/
There is a div #nav which has a fixed position. The site will be mobile optimized so im hiding the browser chrome with the following JavaScript:
setTimeout(function() {
window.scrollTo(0, 1) },
100);
Ive found a bug when viewing the site in an iPhone 3G, iPhone Retina and iPad. If you click on '1' on the front page to take you to the third section, scroll down the page, and then click '< Map' to go to the map section, the nav which now contains the text '< Filters' is in the wrong place. As soon as you scroll up or down the div jumps to the correct place.

Position fixed is not catered for on iOS4/iPhone3GS.... I had the same issue, a fixed header with a back button on it, went wrong with I used scrollTo. The back wouldn't work but a link underneath the header would be clicked My findings below;
Under further investigation with an iOS man, we have discovered it is a bug in Safari on iOS5.
I tried this;
// $('html,body').animate({ scrollTop: scrollto + 'px' }, 'slow')
window.scroll(0,0);
And saw it actually drew the fixed header further down the screen. With the click working.
So I swapped the code back, and although it drew the header correctly at the top, the active click area was still further down the page, though was invisible, was clickable.
Seems they have resolved it testing on iOS6.
I exhausted all kinds of CSS and DOM manipulation, removing, and re-inserting a new header area... nothing works.
So I am 99% sure to post this an THE ANSWER. lol. Though I realise that doesn't help you.

Related

iphone sticky menu jquery onscroll ios 9

This code was working fine on my iphone before updating to iOS 9.0.1 (13A404), but now the same code seems to be working only after finger release, or after the jQuery onscroll ends, when I do a quick swipe leaving the page scrolling...
$(document).on('scroll', function(){
if( $(this).scrollTop() > 0){
$('.menu').addClass('sticky');
}else{
$('.menu').removeClass('sticky');
}
});
The sticky menu just disappears until I release the finger up from the screen, losing the "stickying" effect in realtime during the swipe that I had before in all my websites and that are now broken...
How can solve this problem making them working like I had before? (smooth sticky in realtime)
After observing the same behaviour and testing around a bit, the simplest way is to activate 3D transforms as proposed in a similar question:
.sticky-element {
-webkit-transform: translate3d(0px,0px,0px);
}
I am seeing the same behavior. It seems iOS9 doesn't want to paint position: fixed elements until AFTER a scroll event has ended.
Example: http://senaeh.de/demo/stickyheaders/simple/
The new sticky header will not show until either the page stops scrolling or the user removes their finger from the screen. Other CSS changes such as background-color work as they should.
This is a regression since iOS8 allowed this completely. Sticky headers are unfortunately not smooth as of ios9.0.1. They still work great on aging Android devices so I'm not sure if this is a bug or if Apple is trying to increase battery life.
EDIT: I filed a bug with Apple (#22902083) so let's hope they make an update to remedy this.

Link works in Firefox but not active in Chrome and Safari

On this page: prolitho.com/wp/about
If you click on the first employee picture (Mary) the image and .profile-cover will move out of the way and you will see among other things a linkedin icon.
In Firefox that icon reacts to hover and is clickable. In Safari and Chrome it is inactive. I can't figure out why. Any ideas?
It has to do with the z-index that is being set to -1 for profile-extra so it's not receiving events.
One way to deal with the problem would be to set the z-index of .profile-extra to something higher than 1 while displaying the extra info
It looks like your pulling the logo in as a fontawesome icon.
.fa-linkedin-square:before {
content: "";
}
Chrome seems to be having issues understanding this character.

Fixed background image flickering when slideshow at top of page transitions

This is in Chrome only! I have a div with a fixed background image a ways down after a slider at the top of the page. (It's the section with the vimeo video in it) The background image that is fixed almost completely disappears when the slider advances to the next slide. I though maybe it was a z-index issue and also removed "-webkit-backface-visibility: none;" from the css but neither were the answer. I'm sure it's something to do with the css3 animations but also completely stumped. Any ideas?
A link to the page in question: http://ksdesigning.com/themes/room_html/
Thanks
I hate bugs like this, here is a fix that should work. It just hides the slider once someone has scrolled past it and shows it if they scroll up to it.
$window.scroll(function() {
var _scroll = $window.scrollTop();
if (_scroll >= 650) {
$('#slider').hide();
}else if (_scroll <= _triggerOffset){
$('#slider').show();
}
});
Otherwise play around with the examples on this link. ( I could not get them to work so I made the way above)
Prevent flicker on webkit-transition of webkit-transform

Mobiscroll + Samsung Galaxy S3 + position: fixed = Broken scroller?

We are using Mobiscroll on our mobile website and it works just fine, except on one device: My boss' Samsung Galaxy S3 (runs stock Samsung fw and stock browser, but Mobiscroll works fine with Chrome). It looks like the z-index of all the elements get messed up.
It looks like this:
http://pix.toile-libre.org/?img=1350013732.png
Everything is dark and hard to read, and the numbers go over the arrows.
I played a bit with the CSS and removed the transparent background of the page, which made all the colors go back to normal (I was not able to make it go behind as it should for some reasons). But the numbers of the wheels still goes in front of the arrows.
I played even more with the CSS and figured out that the -webkit-transform3d makes the wheels go in front of everything, like if it had it's own layer on top of everything.
After a while, I finally found that the problem is caused because my menu bars have "position: fixed;" on them so they stick to the viewport. As soon as put them to something else than "position: static;", the browser seems to mess up everything, including Mobiscroll.
I need to keep these menus fixed, and there are other elements in the page that will get "position: absolute;"
Any idea how I should solve this? Should I hack the CSS and JS of Mobiscroll to get rid of the transform3d and the background so it appears to work not bad, or is there a better solution for that horrible device?
Please tell me if you need anything else!
Thanks!
It appears that this is an android 4.0 bug. There is a bug report on it here:
http://code.google.com/p/mobiscroll/issues/detail?id=96
I face this problem also.. its sucks.
The only solution ive found, is to use mobiscroll onShow & onClose events, to hide and show this position fixed element which cause the overlays problem (in may case that was the footer that was position fixed).
$(".date-picker").mobiscroll().date({
onShow: function(html, inst) {
var header = $('div[data-role="header"]');
if(header) header.css('position', 'absolute');
var footer = $('div[data-role="footer"]');
if(footer) footer.css('position', 'absolute');
},
onClose: function(html, inst) {
var header = $('div[data-role="header"]');
if(header) header.css('position', 'fixed');
var footer = $('div[data-role="footer"]');
if(footer) footer.css('position', 'fixed');
}
});
I know its kind of late. But this did the fix for me,
-webkit-backface-visibility: hidden
on the div

Mobile Webkit reflow issue

I've been experiencing an issue in mobile versions of webkit (specifically Webkit 534.46 on iOS 5.1.1 as mobile Safari, and now Chrome for iOS) which doesn't happen on any desktop browser that I've seen. (i.e. the demos below should be viewed on a mobile version of webkit.)
Here is a live example of the issue. The core of the CSS is extremely straight forward. It positions an alphabet index along the left of the page:
#index {
left:0; margin:0; padding:0; position:fixed; top:0; width:3em;
}
The issue happens when an element is fixed position over the top of the body. It is fully able to be interacted with until the scroll changes and then it stops accepting input. If I (manually) jiggle the scroll even one pixel then it becomes active again. The example was kept as simple as possible and does not use any JavaScript. After really hammering on it, I've discovered that it appears that the element thinks it is scrolled but has been visually fixed. In other words, if you click on 'A' then try to click on 'A' again, sometimes you will get a second click in but it will be further down the list. This seemed like a CSS reflow issue to me. I know that mobile webkit attempts to reduce the number of reflows.
Here is a live example of the workaround.
I am able to use JS to force the CSS of the entire document to reflow on scroll (with a throttle which prevents it from happening until 100ms after scrolling) which seems to workaround this issue in the simple example. Unfortunately, this does not help the real world version of this issue.
This is the code for the issue page and the workaround script.
My question is what is happening here and is there a CSS workaround that I am missing? Specifically, I'm curious if any CSS guru can figure out what the layout situation is that prevents the clicks from hitting the correct place on the fixed element? A better understanding might help find a real fix.
Edit: I forgot to mention that the example explicitly forces the viewport to the size of the window. So the user cannot zoom in/out, meaning that the position:fixed should anchor the element to the left side of the window.
Update (2012-09-20): This appears to be fixed in Mobile Safari on iOS 6 (as well as UIWebView). Any workaround should first check to make sure it is on iOS < 6. For example, using CssUserAgent this would look like:
if (parseFloat(cssua.ua.ios) < 6) { /* ... */ }
The answer that actually solved my particular issue was a variation of a solution found in one of #Paul Sweatte's links:
Essentially, a plain div which is taller than the body is added. When it is removed, it causes the body to effectively scroll or reflow. Setting the delay to 0ms between adding/removing is enough to allow the DOM to recalculate without causing any flickering. This was the minimal script I could find which fully solved the problem for all position:fixed elements on my particular instance of this issue.
var hack = document.createElement("div");
hack.style.height = "101%";
document.body.appendChild(hack);
setTimeout(function(){
document.body.removeChild(hack);
hack = null;
}, 0);
Ironically, my original reflow fix (linked to in the question) is now working in my real app, too. Putting a variant of it here in case is useful to anyone else. It can be called on any container element, or if nothing is passed in it reflows the whole document.
var forceReflow = function(elem){
elem = elem || document.documentElement;
// force a reflow by increasing size 1px
var width = elem.style.width,
px = elem.offsetWidth+1;
elem.style.width = px+'px';
setTimeout(function(){
// undo resize, unfortunately forces another reflow
elem.style.width = width;
elem = null;
}, 0);
};
The nice thing about this is that it doesn't require creating / adding / removing elements, just tweaking the container.
My install of iWebInspector is pretty busted right now, but after messing around with jsfiddle and the iOS sim it seems like your hunch is correct - despite being position:fixed, the browser thinks the page has scrolled, and screws up the click targets.
It looks a lot like this is the same issue as iOS Safari: Anchors within a fixed positioned element only work once, which also hasn't been solved with pure CSS. Also related: Fixed position navbar only clickable once in Mobile Safari on iOS5.
Tangentially, and I'm sure it's been noticed already, it's not possible to scroll the left side, so on an iPhone the index only shows A-M.
Looks like this is a known bug:
the core problem is: if the page moves programatically (i.e. the user didn’t cause the scroll) the elements inside the fix element are unavailable.
Use absolute positioning, change the markup, or use one of the hybrid workarounds.
Here's a variation of McKamey's workaround. It avoids reflowing twice, and may help with flickering (depending on your app):
setTimeout(function(){
document.body.style.borderBottom =
document.body.style.borderBottom === 'none' ? '1px solid white' : 'none';
}, 0);
I believe this is better, and achieves the same effect, allowing links to be clickable in fixed footers. Somehow, doing urlbar hiding causes links in the fixed footer to be unclickable until you scroll a little bit. I have seen this too when focusing inputs, and I attach an event handler to all focus events to fire this off as well. I do this with dojo to attach the events.
if(navigator.userAgent.match(/iPhone/i)){
/* The famous iOS can't-click-links until touch fix, I attach onfocus */
query('input,textarea,select', this.domNode).on('focus', function(el){
document.documentElement.style.paddingRight = '1px';
setTimeout(function () {
document.documentElement.style.paddingRight = '';
}, 0);
});
}

Resources