Reputation: 7151
I've got an image loaded into an overflow:auto div. On load, when you scroll the div, the scrollbar vanishes instantly. I can get it to come back if I run, say, animate on the div's height (without even changing the height), but only after it's vanished. After the animate, it's fixed for good.
I can fix this if I remove the -webkit-transform:translationZ(0); from the div's CSS, but I need the performance boost this provides (not for this little test program, but for the code it's derived from), so I can't remove it.
Any idea what's going on here, and how I might be able to fix it?
It's all in a jsfiddle: http://jsfiddle.net/forgetcolor/dB38c/5/
And also below:
HTML:
<div id="overflow"></div>
<p id="btn">click to fix</p>
CSS:
#overflow {
overflow:auto;
width:500px;
height:200px;
/* comment out the webkit-transform and the problem dissapears
* (but I need the transform for acceleration
*/
-webkit-transform:translateZ(0);
border:1px solid #000;
}
Javascript:
var scrollbarWidth = 15;
var r = Math.floor((Math.random()*100000)+1);
//adding r to simulate non-cached images
var pagelink = 'http://lorempixel.com/output/city-q-c-1920-1920-4.jpg?'+r;
$('#overflow').html(
"<img width='485' id='imgload' src='"+pagelink+"' />"
);
$('#btn').click(function() {
$('#overflow').animate({height:200},0);
});
UPDATE: bug report filed: https://code.google.com/p/chromium/issues/detail?id=129186
Upvotes: 2
Views: 3671
Reputation: 732
Adding this to the offending scrollable seems to fix the problem.
-webkit-transform: translateZ(0);
Check out the updated fiddle: http://jsfiddle.net/dB38c/13/
Upvotes: 4
Reputation: 49252
This is indeed a Chrome bug. I can reproduce this in Chrome Stable and Canary (but not in Webkit Nightly). Can you report this to new.crbug.com? The testcase is great, by the way.
In the meantime, you can apply overflow:scroll
conditional on your own calculated size of the internals of the div.
In the case of your code,
var elem = $('#overflow');
var heights = elem.children().map(function(){ return $(this).height(); }).get();
var sum = _.reduce(heights], function(memo, num){ return memo + num; }, 0);
if (sum > elem.innerHeight()) elem.css('overflow', 'scroll');
I'm using underscore for the reduce()
sugar, but you could do it without. Pretty sure there are some answers on SO for calculating sizes of child elements in order to do something like this (that are probably more robust than my approach).
Upvotes: 3