Affix position doesn't reset when scrolling back up #9342

Closed
EnzoMartin opened this Issue Aug 11, 2013 · 13 comments

10 participants

@EnzoMartin

Issue occurs when using a top and bottom offset and scrolling all the way down so that the Affix gets the .affix-bottom class and a style tag with position:relative;. When you scroll back up, it doesn't remove the style tag with position:relative; which thus overrides the .affix class's position:fixed and makes it snap to the top of the page instead of affixing smoothly like when scrolling down

Fiddle: http://jsfiddle.net/H9D4P/

Screenshot of the style tag overriding position:fixed;
affix

@fat
Bootstrap member

this is an issue with your implementation.

Affix toggles between three states/classes: affix, affix-top, and affix-bottom. You must provide the styles for these classes yourself (independent of this plugin). The affix-top class should be in the regular flow of the document. The affix class should be fixed to the page. And affix-bottom should be positioned absolute. Note, affix-bottom is special in that the plugin will place the element with JS relative to the offset: { bottom: number } option you've provided.

try asking in the mailing list if you need help

@fat fat closed this Aug 11, 2013
@EnzoMartin

No, it isn't.

If you look at the fiddle I linked, as well as the screenshot I provided, you'll note, as I described, that when you reach the bottom, the plugin adds a style attribute with position:relative; which will override any classes that Bootstrap or I set, unless I use !important.

@mekwall

@fat Did you check the provided fiddle? It clearly shows that the affix plugin is setting position: relative as a style to the affixed element when hitting the bottom. I don't see how this can be an issue with his implementation.

@EnzoMartin

After getting some time to investigate it more while taking a break from work, I've found that the bug is caused by the usage of jQuery's .offset() here: https://github.com/twbs/bootstrap/blob/3.0.0-wip/js/affix.js#L76 which, as per jQuery's documentation does the following:

The .offset() setter method allows us to reposition an element. The element's position is specified relative to the document. If the element's position style property is currently static, it will be set to relative to allow for this repositioning.

You can read more about how jQuery's .offset() function works here: http://api.jquery.com/offset/#offset2

Since jQuery's .offset() function sets position:relative; (as per the documentation above), Bootstrap's Affix needs to reset it back to position:fixed; if the user scrolls back up, otherwise it stays stuck on position:relative; and thus breaks the Affix functionality.

@cvrebert cvrebert reopened this Aug 12, 2013
@young-steveo young-steveo added a commit to young-steveo/bootstrap that referenced this issue Aug 12, 2013
@young-steveo young-steveo Fixing `position: relative` bug mentioned in Issue #9342 7b11ba1
@ShaunR

@fat I can confirm that this issue exists, i'm not sure were the style attribute is getting set from in the JS but it is being set! Here's my example http://72.1.241.234/affix/

@EnzoMartin

@ShaunR It's from the usage of jQuery's .offset() function: http://api.jquery.com/offset/#offset2

The .offset() setter method allows us to reposition an element. The element's position is specified relative to the document. If the element's position style property is currently static, it will be set to relative to allow for this repositioning.

@fat
Bootstrap member

i fixed your jsfiddle.

http://jsfiddle.net/H9D4P/11/embedded/result/

like i said originally: you must provide a style for affix-bottom.

offset applies position relative if you don't apply position: absolute

@fat fat closed this Aug 17, 2013
@timodewinter

@fat There is still an issue when you set .affix{ top:0px; } instead of .affix{ top:10px; }. When you scroll all the way down and then back up again the #sidebar affix doesn't work, it eventually snaps back into place, but only when you scroll all the way up.

See: http://jsfiddle.net/H9D4P/16/embedded/result/

Tested on OSX 10.9.1 in Firefox 26.0, Chrome 31.0.1650.63, Safari 7.0.1

@nthomson

@timodewinter Did you ever figure this out? I'm having the same issue.

If you scroll all the way down and then back up again the affixed item just sits there until you scroll back to the top of the page.

@cvrebert cvrebert reopened this Mar 6, 2014
@eriknordin

I to have the same problem when having .affix {top: 0; }. When changing to .affix { top: 1px; } it works.

This problem appears in Chrome (Version 33.0.1750.146 m) and Firefox (26.0), not in IE 11 on Win 8.

I initialize affix by:
$('.sticky-menu').affix({
offset: {
top: $(".sticky-menu").offset().top,
bottom: $('footer').outerHeight(true)
}
});

css: .affix-top { }
.affix { top: 0; width: 100%; z-index: 1; }
.affix-bottom { position:absolute; }

@fat fat added a commit that referenced this issue Mar 9, 2014
@fat fat fix #9342 e9cced7
@fat
Bootstrap member
fat commented Mar 9, 2014

fixed by this pr #12982

@fat fat closed this Mar 9, 2014
@mdo mdo added this to the v3.2.0 milestone Mar 9, 2014
@mdo mdo referenced this issue Mar 9, 2014
Closed

v3.2.0 ship list #12736

@vkbansal

I too had the same problem and this snippet fixed the problem

.affix-bottom {
    position: relative
}
@cvrebert
Bootstrap member

Locking per #12982.

@cvrebert cvrebert locked and limited conversation to collaborators Jul 11, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.