In noticed the following behavior when developing a website using Chrome: when I refresh the page while it's being scrolled fully to bottom I can observe a vertical jump.
See the following Bootply.
To reproduce, open the fullscreen preview (the monitor icon on the right), and try the following:
- refresh the page (confirm form resubmission) --> no jump
- scroll to middle, refresh (confirm form resubmission) --> no jump
- scroll to very bottom, refresh (confirm form resubmission) --> vertical jump
The jump is in fact caused by this Javascript that tries to maintain vertical rhythm when page contains figures with .align-center
class:
$(document).ready(function() {
$(window).resize(function() {
var baseline = parseInt($('body').css('line-height'), 10)
$('.align-center').each(function() {
var height = $(this).outerHeight();
console.log(height)
var bottom = baseline - (height % baseline);
if (bottom != 0)
{
bottom += parseInt($(this).css('padding-bottom'), 10)
$(this).css('padding-bottom', bottom);
}
});
}).trigger("resize");
});
Of course removing this Javascript also removes the vertical jump observed. What I don't understand is that padding is applied when DOM is ready so it shouldn't cause visible vertical jumps. I think the jump has to do with the way Chrome handles the viewport when page is scrolled to very bottom but I don't really know how to confirm/infirm this.
When trying this in Firefox or Safari, I don't observe any jump.
Any idea please?
Edit: I opened a bug on Chrome's bug tracker.
In noticed the following behavior when developing a website using Chrome: when I refresh the page while it's being scrolled fully to bottom I can observe a vertical jump.
See the following Bootply.
To reproduce, open the fullscreen preview (the monitor icon on the right), and try the following:
- refresh the page (confirm form resubmission) --> no jump
- scroll to middle, refresh (confirm form resubmission) --> no jump
- scroll to very bottom, refresh (confirm form resubmission) --> vertical jump
The jump is in fact caused by this Javascript that tries to maintain vertical rhythm when page contains figures with .align-center
class:
$(document).ready(function() {
$(window).resize(function() {
var baseline = parseInt($('body').css('line-height'), 10)
$('.align-center').each(function() {
var height = $(this).outerHeight();
console.log(height)
var bottom = baseline - (height % baseline);
if (bottom != 0)
{
bottom += parseInt($(this).css('padding-bottom'), 10)
$(this).css('padding-bottom', bottom);
}
});
}).trigger("resize");
});
Of course removing this Javascript also removes the vertical jump observed. What I don't understand is that padding is applied when DOM is ready so it shouldn't cause visible vertical jumps. I think the jump has to do with the way Chrome handles the viewport when page is scrolled to very bottom but I don't really know how to confirm/infirm this.
When trying this in Firefox or Safari, I don't observe any jump.
Any idea please?
Edit: I opened a bug on Chrome's bug tracker.
Share Improve this question edited May 10, 2022 at 16:17 TylerH 21.1k77 gold badges79 silver badges112 bronze badges asked May 9, 2014 at 18:43 Gregory PakoszGregory Pakosz 70.3k20 gold badges142 silver badges165 bronze badges 3- I don't know if my chrome installation has some kind of problem but I see the jump even if I pletely remove the js and add * { margin: 0 !important; padding: 0 !important; height: auto!important; min-height: 0 !important; } – Jonas Grumann Commented May 20, 2014 at 8:08
- I think you're trying to convert the image container height into a multiple of 20 (line height). If this is correct then your calculations are wrong. 300 is a multiple of 20 in which case no padding is required. – Salman Arshad Commented May 20, 2014 at 9:57
- A possible workaround may be to attach to the onscroll event and assure that the page is always at least one pixel above the very bottom. – Dag Sondre Hansen Commented May 20, 2014 at 11:32
2 Answers
Reset to default 3 +300First of all, I have to disappoint you, as I'm not a Chrome dev or other official source. But I did put some time into the issue and thought I'd share what I found. You know, for posterity.
As you probably have, I put a couple alert
s in the code and tried to observe, what exactly was happening. It seems to me like the viewport is rendered, the Javascript runs, the padding is applied, the entire rest of the content is pushed down, then Chrome realizes and fixes the viewport height to acodate the additional padding. It looks like an honest rendering bug to me.
That said, I did find something that fixed the effect, at least in my tests. I don't know whether this is applicable in your environment, but maybe it does help in diagnosing the rendering issue further.
Simply adding the additional space to a margin, instead of the padding, did it for me.
if (bottom != 0)
{
bottom += parseInt($(this).css('padding-bottom'), 10);
$(this).css('margin-bottom', bottom);
}
Maybe somebody else can e up with an actual explanation. I'd sure like to know what exactly causes this unnerving behavior.
I do not have a plete answer but some observations regarding Chrome:
- Browser can start painting the document before document ready event
- Browser can show vertical scrollbar before document ready event
- Browser can scroll to the previously visible content before document ready event
- Browser can scroll to the previously visible content after window load
Your code seems to add a 20px padding to the figure on document ready event. So here are the consequences:
Scroll to top or middle + Refresh:
The browser scrolls the same content into view that was visible before the refresh. The increase in body height does not affect the scroll position except that the scrollbar changes its height.
Scroll to bottom + Refresh:
The browser tries to align the body to the bottom when possible. It seems to do this twice+. The body is scrolled all the way to the bottom when the content is available. Then 20px is added to the body height on document ready which activates the "scroll down" button. On page load, the browser aligns the body with the bottom again, pushing all the content down by 20px which creates the "vertical jump" behavior.
+ For testing I added $(window).scroll(function() { console.log(arguments); })
. The scroll event fired twice: after document read and after window load.
In summary:
Chrome seems to align the body with the bottom of the page if it was that way before page refresh. And it does so pre-maturely and after the page loads causing the jumping effect.
Firefox seems to follow the same steps. However, it seems like Firefox handles the scroll to bottom case intelligently. Since the body is aligned with the bottom, it makes the layout changes (triggered by padding) in the area above the viewport; increasing the height of scrollbar but not scrolling.