iscroll on iphone: visual distortions. I suspect it's hardware related? - iphone

I wrote a JQM web app for Android and iPhone that runs in a custom native container that comes with a bunch of vendor libraries, including a custom version of iScroll. Recently, we upgraded the libraries from the vendor, including iScroll. Now, iPhone users are seeing visual distortion under certain conditions (screenshot: http://i.stack.imgur.com/mCUyB.png). The distortion correct themselves after scrolling.
Symptoms:
horizontal lines are being drawn on the right of the screen
Elements in the iscroll div are stretching past the right hand side. (Notice the divs has round edges on the left side, but not on the right. This also corrects itself after scrolling.
When both of these conditions are met, it triggers the distortion:
After downloading a larger dataset, causing more DOM elements to be attached to the iscroller
When the user navigates backwards. Essentially, when JQM page and its attached elements go from hidden to visible.
CSS code of the div iscroll:
element.style {
-webkit-transition: -webkit-transform 0ms;
transition: -webkit-transform 0ms;
-webkit-transform-origin: 0px 0px;
-webkit-transform: translate3d(0px, -131px, 0px) scale(1);
}
A few more observations:
I suspect the iscroll is because the previous iscroll version did not use -webkit-transform.
on iPhone, -webkit-transform: translate3d is hardware accelerated.
the distortion is only on iPhone, not on Android.
Not sure what other information I should provide. I could provide the code for the iscroll, but it's 800 lines of code.
This is my first post here. Be Gentle.

I was having some issues with iScroll 5 where images and even text would get distorted when scrolling to some items (works fine on browsers but fails on iPhones/iPads).
I have 4 tabs with one scroll each. The first one works fine (maybe because it has less items?), but the others fail when scrolling to the last item or so.
After some tests, I noticed that removing the CSS transition on the container (with the #id that I'm using to call the iScroll), solved the problem. I'm still keeping the transitions though. I just had to move it to a different container down on the DOM tree. (on my case it was just a fade in effect when the scroll finishes loading).
It's a really strange bug... Hope it helps you solve your problem too.

Related

Images disappear during translate3d on Chrome for iPhone and iPad

I have a coverflow type image gallery that I have created for mobile picture viewing. The first iteration lives here: http://codepen.io/jasonmerino/pen/Fsloq.
I've wired up the touch events and all seems to be going well for mobile Safari on iPhone and iPad, but when I go to view it on Chrome for iPhone or iPad the images disappear during part of the CSS translate3d which moves the images to the sides.
I have added -webkit-backface-visibility: hidden; to all of the markup that comprises the swiper, which does not fix this disappearing act my images are doing.
What am I missing here? Any help would be appreciated. Thanks!
The problem was with the peice of code where I was removing inlined CSS translate3d. The code that I had in place dealt with removing the translate by just re-assigning the background images.
for (var i = 0; i < images.length; i++) {
$el.images.eq(i).css('style', 'background-image: url(' + images[i].src + ')');
}
In mobile Safari this was fine, but in Chrome the images reloaded when I re-assigned the background image, hence the disappearing act. So I adjusted my code to be a little smarter, and concise, so that I only removed the translate from the inlined styles.
$el.images.css('transform', '');
Turns out that when you pass an empty string as the value to a CSS attribute in jQuery they just remove the style out for you instead of leaving it there but blank. Makes sense, but I never knew that before.
Anyway, that's what fixed it for me.

How can I turn off hardware acceleration for certain HTML elements via CSS?

I created a very complex web app using HTML5, CSS3 and jQueryMobile.
It seems like jQueryMobile turns on hardware acceleration here and there via translate3D and/or translateZ.
Now I want to turn this off for certain HTML elements.
This gives me two questions:
Is there a css property/attribute or something that I can use to tell the browser to turn off hardware acceleration for certain elements?
If not: I will have to find the places where either translate3D or translateZ is used and simply remove them, right? How can I do that? The whole markup is very complex with many HTML elements. I can't go through each element in the inspector and search for it.
Update: The reason why I want to fix this
In my web app there are some elements which need to be swipeable (e.g. an image gallery). In this case I need hardware acceleration. Same for div containers that require iScroll and every other element which should be animated (e.g. slide- and fade-animations).
However, there are many parts of the app which are static (not animated). Using a special startup option in Safari, I was able to make the parts which get hardware-accelerated visible. This way I noticed that THE WHOLE app gets hardware-accelerated, not only the necessary parts.
IMHO this is not a good thing because:
Accelerating the whole thing will cause heavy load to the GPU which makes the whole app stutter while scrolling.
AFAIK it's best practice to let the CPU do the static stuff while the GPU only handles all the fancy animated stuff.
When animations have ended, hardware acceleration should be deactived because it's not necessary anymore and would shorten battery lifetime.
After going through thousands of thousands of lines of CSS code, I found this:
.ui-page{-webkit-backface-visibility: hidden !important}
This was active for all pages and caused the problem. Removing that line fixed it for me.

Unintrusive image loading indicator on iphone

I'm looking for a simple method to implement a 'loading' indicator on img elements for Mobile Safari (and possibly other mobile agents). At first sight, using the background: property on such elements seems the way to go. There are two problems though:
Agents tend to start rendering already when only part of the image is loaded. This looks pretty weird in combination with the loading indicator image.
I'd like to apply a css3 rotation animation (spin) to the loading indicator (and not to the final image).
Setting the content css property to '' and a simple class-tag that indicates the image is loading would work around this. Unfortunately, this also somehow prevents Mobile Safari from doing the animation (although it seems to work fine in Chrome).
Other (and perhaps better) solutions would involve multiple elements, but I am specifically trying to prevent this. Css pseudo classes :before or :after also do not work in combination with animations.
My attempt thusfar: https://gist.github.com/1225523#file_loading.html
Any suggestions?
I would suggest spin.js that is all CSS3 based and it don't use any image. You can customize your spinner very easy.
SPIN.JS

Remove horizontal movement / wiggle from iPhone optimized pages

I'm trying to optimize our News pages for iPhone. One problem I've noticed is that I'm able to tap and move the page horizontally (i.e. wiggle).
My question is, how I can prevent this horizontal movement from happening?
All of our News pages have this problem. Here are a couple examples:
With picture
Without picture
Something is definitely set greater than your device width. Add the following to your css to find the culprit.
* {
border-style:solid;
}
You can then narrow down your search by setting border-color:red; to individual classes/tags/ids.
Add "overflow-x: hidden" on the body.
You can try setting user-scalable=0; and see if that has any effect.
This just happened to me too and it was the result of an extra closing div tag. Once I removed the extra </div>, the horizontal "wiggle" didn't happen any more.
I too, had the iPhone "wiggles" on a web page. It ended up being caused by an image that was wider than the column width it sat in (it was the last column in the row using Twitter Bootstrap). You might be thinking "obvious", but it's hard to spot when the image background matches the page background.
Just make the image responsive, or smaller than the column width - that solved it for me.
Taking the idea from other websites, most of big sites have a mobile site. look at those (the only one i know is facebook m.facebook.com) you can maybe see how the css is done. possible way of doing this is %. I would suggest to take out the sidebar for the mobile version. big pictures should be taken out or be resized so the browser doesn't have scroll bar side to side.

Blurred text in Iphone 4 browser when loading content dynamically

I am using the Jquery/Jqtouch libraries for an iphone compatible site. I am now stuck with a problem just in iPhone 4 (not in 2g, 3g or 3gs) where the text becomes blurry on one specific scenario. Below is how it happens
The site has one common div container.
<div id="container"></div>
The container is filled with content dynamically based on the user action. Below is the function that does that.
function loadPage(url, section, callback) {
$('#container').empty();
$('#container').load(url + ' ' + section, loadComplete(section));
}
One sample call to the above function
loadPage("Data.htm", "#Friends", null);
Basicaly eveything works fine except on one scenario where the amount the data on the container is huge (ie the #container height increases to 1500px+ not predictable). Now if i replace it with smaller data for different tabs on the same container then the text becomes blurry. Attached is the image
http://i.stack.imgur.com/XE9q4.png
Did anyone come across this scenario. Thanks in advance.
Try closing all your running apps besides safari. It sounds crazy but we have the same problem on the ipad and it just seems to be running out of memory at some point. Closing all the apps stops it. Other thing that seems to make a difference is -webkit-overflow-scrolling:touch, if it doesnt have this property then it doesnt seem to have the problem described.
i was able to fix this by applying the same settings to reduce flicker on the element in webkit browsers:
-webkit-perspective: 1000;
-webkit-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
Graphics elements must be "aligned" with the pixels on the screen; coordinates must always expressed as integral values and not floating values. If not, the subpixel rendering engine of the GPU would make it blurry, which is not a problem with animation but definitely one with static images.
In the native SDK, we have to make sure everything is aligned (such as using CGRectMakeIntegral()).
Since you're using a web framework, it's more difficult to tell how to exactly how fix the problem, but I would try to adjust the sizes of your to a precise size and not let the framework figure it out.
What content do you load? Images? Text? There's an internal limit on image sizes for the iPhone (about 4 Megapixels or so). It looks like the phone is trying to reduce the memory load of your website and reduces the resolution to non-retina values.
I can't say more without you posting code.
This is a shot in the dark, but have you aset your sizes using pt values for your block elements, and em for your text?
The iphone4 resizes your content to fit its higher-res Retina display (compared to the older iphone), and with that scaling i have sometimes noticed blur when using pixel values for block height, width, font size, etc.
Very hard to diagnose without seeing the actual code, but could be the issue.
In my case it was CSS
-webkit-transform: translateZ(0);
applied to one of the elements in body. So as Ariejan said, it's removing transition property that fixes it.
body{ text-rendering: optimizeLegibility}
could solve this issue, worth a shot if you haven't included it already
Sometimes, Text blurry may be cause of the iScroll Plugin. Did you use this?
Try to comment
trnOpen = 'translate' + (has3d ? '3d(' : '('),
trnClose = has3d ? ',0)' : ')',