Changing Display Resets Scroll Offset

In Chrome 5, Safari 4, Opera 10.53 and sometimes Firefox (although I was unable to reproduce it in this test case), changing the visibility of the element by toggling display:none will cause the scroll offset to reset to zero. Toggling visibility:hidden does not seem to trigger the same problem.

Scroll the container and then toggle the classes applied.

Class applied:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

I haven't tested this in Internet Explorer, yet. Feel free to report in the comments.

Published June 10, 2010
Categorized as HTML and CSS
Short URL: https://snook.ca/s/981

Conversation

22 Comments · RSS feed
Ryan Tenney said on June 10, 2010

Just tested it in IE 8, and the behavior is the same.

Gregory Papangeles said on June 10, 2010

IE testing results:

IE8: display:none resets the scroll offset, visibility:hidden does not
IE7: scroll offset is not reset in any case
IE6: scroll offset is not reset in any case

NICCAI said on June 10, 2010

Think this is a logged issue for Chromium (maybe a webkit issue?). As a work around, you could probably set the height to 0 or push it off stage.

Ara Pehlivanian said on June 10, 2010

Makes sense though, if you think about it. Playing with visibility just turns off the element's appearance whereas setting display to none seems to cause the object in memory to destroy and then re-render it when its display value is reset.

jen said on June 10, 2010

Same results as Gregory for IE.

Windows Firefox scrolls were not reset.

Windows Safari displays the same behavior as Mac.

Windows Chrome reset the scroll for display:none, but didn't for visibility.

riddle said on June 10, 2010

I made a quick test that caches element.scrollTop if anyone’s interested in a workaround:

http://riddle.pl/public/tests/display-scrolltop/index.html

NICCAI said on June 10, 2010

Just tested the CSS fix for this - add height: 0 to your .visibility class and use this in conjunction with visibility hidden (just make sure you work out the specificity, #a has a height set in your example that needs to be over-written).

Iffy said on June 10, 2010

The latest FF - scroll position remains.

Sebastian Werner said on June 10, 2010

In the qooxdoo framework we have a special handling for automatically restoring the position of scroll containers when showing them again. This is indeed a bug (or missing feature) in most browsers. That visibility don't shows the issue is quite logical as the element is still being computed and rendered - just not shown.

Sebastian Werner said on June 10, 2010

One thing to add: Even more complicated is, when the scroll-able area is not the thing which has the scroll bars but a children inside of it. Think about dragable windows using JavaScript with a scroll-area inside.

Simon Sigurdhsson said on June 10, 2010

This does make sense; setting display to none has pretty much the same effect as removing it, and thus also removing its properties. I don't think this should be classified as a bug, even if it seems counter-intuitive or wrong to some people.

Tim McCormack said on June 10, 2010

Firefox 3.5.9 on Ubuntu Linux 9.10 64-bit: Scroll offset preserved both ways.

Olivier Cuenot said on June 10, 2010

Pressing F5 resets scroll offset in Chromium, not in Firefox.

Lea Verou said on June 10, 2010

Good one!

Did you report the bug to the Webkit and Opera teams?

Jonathan Snook said on June 10, 2010

@Lea Verou: I did not. The behaviour seemed reasonable consistent across multiple products that it was unclear whether this was by design or a bug.

Lykope said on June 11, 2010

Safari 5 (Mac): display:none reset the scroll offset, visibility:hidden does not.

Ryan Corradini said on June 11, 2010

FF 3.0 on WinXP behaves correctly (scroll position preserved)

Divya said on June 11, 2010

The spec says "the element and its content are removed from the formatting structure entirely" which is consistent with what you see. The visibility property does not remove the element, but merely makes it invisible.

Richard Fink said on June 16, 2010

+1 on the "makes sense" aspect. Changing the offsetHeight of the page to, essentially, zero, *should* act as a kind of soft refresh.
Interesting observation.

Tasarım said on June 21, 2010

I confirm Jonathan that in IE8, display:none resets offset while visibility does not.

Sean Fousheé said on June 27, 2010

Considering the W3C spec states, as Divya pointed out:

"... the element and its content are removed from the formatting structure entirely."

would certainly explains why this behavior is considered normal. However, the spec does not state that the element is destroyed or removed from memory as Ara suggested. I would suggest crafting a workaround using JavaScript to remember the scroll position upon removing it from the structure, then setting the position when the element is called again.

Douglas said on July 05, 2010

This seems odd. But couldn't you record the scroll offset in a javascript variable in an onkeydown event and reapply it to the area when it's subsequently displayed?

Sorry, comments are closed for this post. If you have any further questions or comments, feel free to send them to me directly.

Want to learn about scaling CSS for large projects?

I'm available for full and half-day workshops on scalable CSS architecture. I can provide on-site training for your team. Interested?
Get in touch.