My initial guess is that the answer is no, because of evidence presented here:
.nicescroll/wiki/Native-scroll-vs-Hardware-accelerated-one
I can notice qualitatively that the "HW accelerated" version scrolls smoother on my puter. I run a 120Hz monitor. This suggests that the second method is faster and more efficient.
For an HTML element such as
<div id="a" style="overflow-y: hidden; height: 100px">
Content <em>which exceeds 100px in height</em>
<img src='lolcat.png' alt='lolcat'/>
</div>
I suppose a straightforward way for 3D hardware accelerated layout to be implemented is that the full height of the div is rendered and then this output is loaded as a texture of the full height, and then the texture coordinates used to render the actual div will reveal only 100px at a time.
My question is related to how the scrollTop
property should in theory do this but it seems that at present there is a much better chance of obtaining the behavior I described by using TWO elements like so:
<div id="a" style="overflow-y: hidden; height: 100px; position: relative">
<div style="position: relative">
Content <em>which exceeds 100px in height</em>
<img src='lolcat.png' alt='lolcat'/>
</div>
</div>
Where instead of setting the scrollTop
property of document.getElementById('a')
I set the CCS3 -webkit/moz/ms/o-transform
property to a 3D value with a corresponding negative Y-axis pixel value.
What's the most efficient way to do scrolling with CSS3? In particular, how can I structure my DOM to have the best chance of getting the most straightforward implementation of scrolling (not causing a re-draw of inner contents when scrolling an element)?
Update: I have been using a really nice smooth scroll plugin for Chrome, which seems to use JS to assign the scrollTop offset on the page to achieve the scroll rendering, which seems to indicate that if this were not hardware accelerated, the performance couldn't really keep up with the screen refresh rate (120Hz) without lots of CPU usage. Still, this kind of speculation remains extremely unscientific. The conclusion I'm going with at this point is that browsers have the freedom to accelerate anything that they choose to within reason so the answer is a resounding maybe.
My initial guess is that the answer is no, because of evidence presented here:
https://github./inuyaksa/jquery.nicescroll/wiki/Native-scroll-vs-Hardware-accelerated-one
I can notice qualitatively that the "HW accelerated" version scrolls smoother on my puter. I run a 120Hz monitor. This suggests that the second method is faster and more efficient.
For an HTML element such as
<div id="a" style="overflow-y: hidden; height: 100px">
Content <em>which exceeds 100px in height</em>
<img src='lolcat.png' alt='lolcat'/>
</div>
I suppose a straightforward way for 3D hardware accelerated layout to be implemented is that the full height of the div is rendered and then this output is loaded as a texture of the full height, and then the texture coordinates used to render the actual div will reveal only 100px at a time.
My question is related to how the scrollTop
property should in theory do this but it seems that at present there is a much better chance of obtaining the behavior I described by using TWO elements like so:
<div id="a" style="overflow-y: hidden; height: 100px; position: relative">
<div style="position: relative">
Content <em>which exceeds 100px in height</em>
<img src='lolcat.png' alt='lolcat'/>
</div>
</div>
Where instead of setting the scrollTop
property of document.getElementById('a')
I set the CCS3 -webkit/moz/ms/o-transform
property to a 3D value with a corresponding negative Y-axis pixel value.
What's the most efficient way to do scrolling with CSS3? In particular, how can I structure my DOM to have the best chance of getting the most straightforward implementation of scrolling (not causing a re-draw of inner contents when scrolling an element)?
Update: I have been using a really nice smooth scroll plugin for Chrome, which seems to use JS to assign the scrollTop offset on the page to achieve the scroll rendering, which seems to indicate that if this were not hardware accelerated, the performance couldn't really keep up with the screen refresh rate (120Hz) without lots of CPU usage. Still, this kind of speculation remains extremely unscientific. The conclusion I'm going with at this point is that browsers have the freedom to accelerate anything that they choose to within reason so the answer is a resounding maybe.
Share Improve this question edited Apr 19, 2013 at 21:19 Steven Lu asked Aug 17, 2012 at 23:35 Steven LuSteven Lu 43.5k62 gold badges219 silver badges381 bronze badges 3- Are you trying to implement a custom scrollbar or scroll event (e.g. animated transition from scrollTop 0 to 100)? or just looking for the most efficient way to structure the page when there are boxes the user will scroll themselves? – Jed Watson Commented Dec 10, 2012 at 11:49
- FWIW in the example you link to, the 'HW' accellerated scroll is significantly jumpier in Safari 6.0.2 on OS X 10.8.2 – Jed Watson Commented Dec 10, 2012 at 11:52
- @JedWatson I see the opposite effect. However I really don't like that test site/page very much, the entire experience is quite flaky feeling. Basically I'll just have to e up with my own benchmarks it looks like. – Steven Lu Commented Dec 10, 2012 at 16:53
3 Answers
Reset to default 5According to the page you mentioned, hardware acceleration depends on if the browser supports hardware acceleration.
Div with wrapper can be hw accelerated. (if browser support it)
So I think your idea of nesting two divs will create an easier way of achieving what you want. But to answer your question, scrollTop
is only hardware accelerated in browsers that support hardware acceleration.
- Firefox 4.0 beta 5 supports HW acceleration.
- IE 9 beta supports HW acceleration.
- Chrome 6+ supports HW accelerated position.
Safari and Opera have yet to support hardware acceleration.
This is according to this page from 2010. http://www.webmonkey./2010/09/a-guide-to-hardware-acceleration-in-modern-browsers/
According to http://arstechnica./information-technology/2012/06/opera-12-arrives-with-webcam-apis-and-experimental-webgl-support/, Opera 12 supports hardware acceleration.
According to TechCrunch, Safari 5 for Windows supports hardware acceleration.
According to Apple Safari's website, Safari 6 supports hardware acceleration.
Sorry! I had links to the TechCrunch article and Safari's website, but I can only use two hyperlinks.
EDIT:
In order to answer the question better, I add to the question. The most efficient way to do scrolling with CSS3 is overflow: scroll;
or overflow-x: scroll;
. The overflow:
CSS property is more efficient CSS than scrollTop
because scrollTop
is a jQuery tag, which uses JavaScript. So using scrollTop
isn't CSS, it's JavaScript. Also, using CSS is also the most straightforward method of achieving horizontal scrolling because it doesn't require importing jQuery library or having JavaScript enabled.
I pletely agree with you by saying that there's a much better chance of obtaining the behavior you described by using two div
tags and CSS instead of using jQuery/JavaScript.
Unless, you want to be able to automatically scroll to another location, when using scrollTop
you can effectively scroll to different locations by using a button or link.
$(document).ready(function() {
$('a[href=#top]').click(function(){
$('html, body').animate({scrollTop:0}, 'slow');
return false;
});
});
This jQuery code using scrollTop
makes all <a href="#top">top</a>
animate the scroll to the top instead of just jumping. When using CSS to scroll, you don't get these animated scrolls. Also, you could use this method to scroll to a different point horizontally or vertically by setting the ID of multiple div
tags and editing the above code to suit your needs. This is from http://www.electrictoolbox./jquery-scroll-top/.
scrollTop
is not hardware accelerated. The best way I found that can generate a smooth scrolling even on a mobile device is to force a css3 hardware acceleration bined with a transition.
I'll assume you have jQuery so I'm using that syntax for clarity purposes, all I'm doing is setting css attributes and other basic calls.
var $body = $('body');
function scrollTop(scrollPosition) {
// account for the current scroll position
var scrollDiff = $body.scrollTop() - scrollPosition;
// use css transition
$body.css('transition', '.5s');
// translate3d forces hardware acceleration, second param is 'y'
$body.css('transform', 'translate3d(0, ' + scrollDiff + 'px, 0)');
// revert back to native scrollTop
$body.bind('transitionend webkitTransitionEnd', function(event) {
$body
.scrollTop(scrollPosition)
.css({'transition': '', 'transform': ''})
.unbind(event);
});
}
Note: I did notice that the transitionend
event isn't always reliable on mobile; this makes the "revert back to native scrollTop" portion of the code appear glitchy. I think the best approach is to take this further and implement your own scrollbar without using scrollTop. The second param of translate3d()
divided by the height of the container will be the location (in percentage) of your scroller in terms of the trackbar.
document.getElementById("a").scrollTop
is more efficient because it's been around for longer. Browser's have had over 10 years to optimize it.