Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bootstrap-affix.js: using Chrome, affixed menu moves violently up and down each time one scrolls to the bottom of page #4647

Closed
tim-peterson opened this issue Aug 23, 2012 · 109 comments
Labels
js
Milestone

Comments

@tim-peterson
Copy link

@tim-peterson tim-peterson commented Aug 23, 2012

I'm using Chrome version 21 and Mac OS X 10.7.

I don't have this same problem on Firefox 14, Safari 6, or Opera 12.

@michalKopec

This comment has been minimized.

Copy link

@michalKopec michalKopec commented Aug 23, 2012

Did you try to style the .affix-bottom? I had a similar jumpy experience with my affixed

. Adding .affix-bottom to CSS and styling it fixed the jumping at the bottom of the page.

@tim-peterson

This comment has been minimized.

Copy link
Author

@tim-peterson tim-peterson commented Aug 24, 2012

@michalKopec thanks, so the menu div gets the affix JS and a separate footer div gets the .affix-bottom class? might you explain in code what you mean?

@mdo

This comment has been minimized.

Copy link
Member

@mdo mdo commented Aug 27, 2012

The bottom bound can fix this, yes. Also, margin on the bottom of an element can cause the jumping, so double check that.

@mdo mdo closed this Aug 27, 2012
@tim-peterson

This comment has been minimized.

Copy link
Author

@tim-peterson tim-peterson commented Aug 28, 2012

just to be clear, the behavior I observed was on the twitter bootstrap site itself, not my own html.

@fat

This comment has been minimized.

Copy link
Member

@fat fat commented Aug 28, 2012

@tim-peterson weird, i can't reproduce this (and i have an identical setup). What page are you seeing this on? fullscreen? etc?

@fat fat reopened this Aug 28, 2012
@tim-peterson

This comment has been minimized.

Copy link
Author

@tim-peterson tim-peterson commented Aug 28, 2012

http://twitter.github.com/bootstrap/javascript.html, scroll down all the way to the bottom using Chrome 21.0.1180.82, not fullscreen.

the affix menu,<ul class="nav nav-list bs-docs-sidenav affix-bottom">, goes berserk because the classes affix-bottom and affix get toggled rapidly.

@mspivak

This comment has been minimized.

Copy link

@mspivak mspivak commented Aug 28, 2012

Same issue here on a custom implementation. Classes affix and affix-bottom get toggled rapidly while scrolling (and the affixed element exceeds the desired bottom offset). Using this:

$('.title').affix({ offset: { top: 350, bottom: 1500 } })
@mdo

This comment has been minimized.

Copy link
Member

@mdo mdo commented Aug 28, 2012

I'm not seeing this at all and have the same version of Chrome.

@tim-peterson

This comment has been minimized.

Copy link
Author

@tim-peterson tim-peterson commented Aug 28, 2012

maybe its just a Mac trackpad issue, i'm using OS X 10.7.4 and have my system preferences->trackpad "Tracking speed" set to the 4th tickmark out of 10 (going left to right).

Btw, sorry to keep wasting your time on this, its not a big deal to me personally but can't hurt to have a record of this issue for others.

@oxideous

This comment has been minimized.

Copy link

@oxideous oxideous commented Aug 29, 2012

I am also experiencing this issue, though I am on Windows 7. I experienced this issue in Chrome and Firefox. I believe at one point I had it functioning properly but through editing further this flickering behavior began to happen. I suppose there may be an error in my code, but if it is happening to others as well perhaps there is a bug.

@phaseOne

This comment has been minimized.

Copy link

@phaseOne phaseOne commented Aug 29, 2012

I am also experiencing this issue. I'm really stuck here. I can't figure out what is going wrong. But I have an additional problem with absolute positioning. The toggling of the affix and affix-bottom classes are sequential and not random. Here's what I've found so far (and my code):

Live Example

http://phaseone.me/internets/github_issues/bootstrap/4647/prod/Printed-Tags.html

The JS

// DYNAMIC SUBNAV
// --------------
$('#subnav-list').affix({
  offset: {
    top: function() {
      brw = $(window).width();
      if (brw >= 1200) return 114;
      // Still need to include other widths
    },
    bottom: 171
  }
});

The HTML

The whole page: https://gist.github.com/3517294

Here's a screencap of the relevant section: http://grab.bovie.me/fJhS

The CSS

#subnav-list.affix-bottom {
  position: absolute;
  top: auto;
  bottom: 126px;
}
#subnav-list {
  width: 240px;
  padding: 15px;
  margin: 30px 0 0 0;
}
#subnav-list.affix {
  top: 50px;
  position: fixed
}

The other problem

Instead of the nav-list positioning itself to the page, it is somehow relevant to .subnav. Despite having the style the same as the bootstrap docs, it's positioned wrong.

With .affix-bottom:

> $('#subnav-list').offset().top
  76

With .affix:

> $('#subnav-list').offset().top
  2574
@tim-peterson

This comment has been minimized.

Copy link
Author

@tim-peterson tim-peterson commented Aug 30, 2012

@phaseOne , weird i'm not seeing this issue on your site though I'm still seeing it on the twitter bootstrap site.

@laszlo-horvath

This comment has been minimized.

Copy link

@laszlo-horvath laszlo-horvath commented Aug 31, 2012

Having the same issue with custom implementation. Any updates on this issue? It would be really important for me.

@tonybruess

This comment has been minimized.

Copy link

@tonybruess tonybruess commented Aug 31, 2012

I'm having this issue as well.

@laszlo-horvath

This comment has been minimized.

Copy link

@laszlo-horvath laszlo-horvath commented Sep 1, 2012

I figured out that the main problem is when the "affix" and "affix-bottom" CSS classes are toggled the CSS on the element are also changing aswell. And the jumpy experience caused because the top and bottom properties are changing from "auto" to a fix value.

For example in my case:

.affix { position: fixed; top: 40px; bottom: auto; }
.affix-bottom { position: fixed; top: auto; bottom: 595px; }

If I give a fix value for both classes it won't jump anymore but in my case for the bottom class I would need a negative top value because my element is higher than the avalaible space I have for it in my layout. That negative top value should be calculated by the plugin..

@fat

This comment has been minimized.

Copy link
Member

@fat fat commented Sep 5, 2012

You guys should fix this, i have faith in you bros

@tim-peterson

This comment has been minimized.

Copy link
Author

@tim-peterson tim-peterson commented Sep 5, 2012

@fat since you aren't working at Twitter are you also not working on Bootstrap anymore? Regardless, what will you be up to now?

I'm just curious as someone who is eternally grateful for your and Mark's colossal contribution to the community,

@vaionicle

This comment has been minimized.

Copy link

@vaionicle vaionicle commented Sep 5, 2012

I had the same issue and i made a patch for it,

https://github.com/vaionicle/bootstrap/commit/8a74ad7b888d1f3d07845d36ddb65d0914eeec32

try it and let me know if it is working.

@phaseOne

This comment has been minimized.

Copy link

@phaseOne phaseOne commented Sep 5, 2012

Patch doesn't work for me. Now the nav toggles between affix-top and affix-bottom rapidly.

@kzxtreme

This comment has been minimized.

Copy link

@kzxtreme kzxtreme commented Sep 6, 2012

I'm using Mac OS X 10.8.1, Firefox 15.0 and Chrome 21.0.1180.89.
This patch works fine.
kzxtreme@be411d8

@tim-peterson

This comment has been minimized.

Copy link
Author

@tim-peterson tim-peterson commented Sep 6, 2012

@kzxtreme thanks!

@laszlo-horvath

This comment has been minimized.

Copy link

@laszlo-horvath laszlo-horvath commented Sep 8, 2012

None of those patches work for me. (Windows 7, Chrome 22 beta).

@thealexbaron

This comment has been minimized.

Copy link

@thealexbaron thealexbaron commented Sep 13, 2012

I'm experiencing the same issue - Google Chrome 21.0.1180.89 m - Windows XP. Seems like we already have a few examples, so let me know if I need to contribute another one.

After digging into the code a little bit, it looks like position.top has a value that we're not expecting. Once you're in the bottom offset range, position.top will bounce between the actual top offset, and a negative number.

Maybe that's helpful. Maybe not.

@bogdan-litescu

This comment has been minimized.

Copy link

@bogdan-litescu bogdan-litescu commented Sep 14, 2012

It happens to me too. The moment the element changes from fixed to static, position.top changes too causing the calculations to alternate.

@bogdan-litescu

This comment has been minimized.

Copy link

@bogdan-litescu bogdan-litescu commented Sep 14, 2012

I removed some borders and padding for the root affix element and the issue went away mostly. It only happens for +/- 20px around the place where it's supposed to change from fixed to static.
I'd still like to get it fixed completely.
I tried the 2 patches. The first introduces the issue again when I scroll beyond the bottom affix, the 2nd patch introduces the flicker while I scroll down until the affix becomes changes from fixed.

@ZetIsDeadBaby

This comment has been minimized.

Copy link

@ZetIsDeadBaby ZetIsDeadBaby commented Sep 14, 2012

Can confirm, I'm having same issue on custom implementation.

@mdo mdo mentioned this issue Sep 14, 2012
@cundd

This comment has been minimized.

Copy link

@cundd cundd commented Jul 8, 2013

I fixed it for me by re-checking the position:

    ...
    this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))

    // It changed so recheck
    if (affix === false && !this.recheck) {
        this.recheck = true
        this.checkPosition();
        this.recheck = false;
    }
}
...

This may produce a lot of overhead, but forces the Affix to check the element's position again, after it did remove the 'affix-bottom' or 'affix-top' class.

Finally it 'snapped' quite smoothly when setting

body {
    position: relative;
}
.affix-bottom {
    position: absolute;
    top: auto;
    bottom: 120px;
}

and

$(someelement).affix({
        offset: {
            top: 10 // Or whatever top-value
            bottom: 120 // Same as in the CSS above
        }
    });
}
@jambox

This comment has been minimized.

Copy link

@jambox jambox commented Jul 16, 2013

Finally got it! @stefanozoffoli, your code and @pascalculator, your advice (to disable the plugin and append the CSS classes one by one to make sure they're doing what I want) helped me iron this out after a night of frustration. Appreciate it!

@CMCDragonkai

This comment has been minimized.

Copy link

@CMCDragonkai CMCDragonkai commented Jul 20, 2013

This should really go into the documentation.

@fat

This comment has been minimized.

Copy link
Member

@fat fat commented Jul 26, 2013

if you're following along – i've somewhat changed how affix works…

in 3.0.0 there are still 3 states: affix-top, affix, and affix-bottom.

The major difference however is that the styles for affix-bottom are set by the plugin based on the offset that you provide.

For example: if you say offset: { bottom: 20 } we will automatically position your element absolutely 20px from the bottom (doing the math etc for you).

You can take a look at the bootstrap 3 docs to see it in action… but it seems to be behaving a bit better

@brunolazzaro

This comment has been minimized.

Copy link

@brunolazzaro brunolazzaro commented Jul 26, 2013

Nicee to see this has been finally resolved!

@geofili

This comment has been minimized.

Copy link

@geofili geofili commented Sep 25, 2013

I am getting flickering in bs3 version of the affix plugin :(

It only happens if the affixed container > viewport height

As you scroll towards the bottom of the page, it toggles between affix and affix-bottom class causing the flicker.

@cvrebert

This comment has been minimized.

Copy link
Member

@cvrebert cvrebert commented Sep 29, 2013

@geofili Please file a new issue with a live example of the problem.

BertrandBordage added a commit to BertrandBordage/bootstrap that referenced this issue Oct 22, 2013
@dmstocking

This comment has been minimized.

Copy link

@dmstocking dmstocking commented Oct 31, 2013

My problem was that the body was larger then document. So the height calculation would always be off. I just changed $(document).height() to $('body').height().

EDIT: also had to make body position: relative

@markushausammann

This comment has been minimized.

Copy link

@markushausammann markushausammann commented Nov 4, 2013

Such threads are perfect examples of how much CSS is broken.

@bondydaa

This comment has been minimized.

Copy link

@bondydaa bondydaa commented Nov 8, 2013

@cundd 's recheck if statement solution fixed my problem. I wasn't having an issue with flickering but with my affixed nav getting it's 'affixed-bottom' and style removed in firefox. This is happening for me only in Firefox and it happens on http://getbootstrap.com/javascript/ for me as well.

To recreate:
when the page first loads, continuously scroll all the way to the bottom of the page (it takes awhile on the bs page, my page was much smaller). once you hit the bottom the affix-bottom and inline style that gets applied get removed and the class will revert to 'affix' cause the nav (or whatever you have fixed) to be placed on top of your footer. If you click or scroll up again it will apply the correct affix-bottom again.

happening in firefox 17.0.7 and 25.0 (also just realized my work machine is behind so downloaded the latest version to test). The problem did not happen for me in chrome or ie8.

@jensdeschrijver

This comment has been minimized.

Copy link

@jensdeschrijver jensdeschrijver commented Jan 3, 2014

This is my solution:

In het file affix.js of bootstrap.js within the affix function you find "Affix.prototype.checkPosition". At the bottom of that function, you have:

if (affix == 'bottom') {
    this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() })
}

Change it to:

if (affix == 'bottom') {
    this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() }).css({ position: '' })
}

In your css (or less) add this:

.affix-bottom {
    position: relative;
}

It solves the problem for me.
The same for #6575

@devmatt

This comment has been minimized.

Copy link

@devmatt devmatt commented Jan 29, 2014

document.body.offsetHeight reports an incorrect (or at least unexpected) height, when html, body { height: 100% } is set in the css.
scrollHeight or $(document).height() report the correct height.

Changing the following (along with following the instructions regarding setting the .affix-bottom styling) solved my issues.

From

this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() })

To

this.$element.offset({ top: scrollHeight - offsetBottom - this.$element.height() })
@kevinglover

This comment has been minimized.

Copy link

@kevinglover kevinglover commented Feb 4, 2014

I added a css rule that worked for me:

@media (max-width: 767px){
    .affix,
    .affix-bottom{
        position:relative;
    }
}
@lizsterine

This comment has been minimized.

Copy link

@lizsterine lizsterine commented Feb 24, 2014

I've been having a flickering problem also. For my scenario it seemed to be a javascript position calculation problem in the checkPosition() function.

Here is a gif of what I want my affix to do:
affix-animation-eg

What is happening, that when my div has the class of "affix-top" - a.k.a when it's scrolling WITH the parent - the javascript was calculating that the bottom of my div was reaching the offsetBottom when in fact the bottom of the div wasn't moving towards the offset at all. If I removed following the line in Bootstrap's checkPosition() function the calculations are then correct and I no longer get the flicker:

if (this.affixed == 'top') position.top += scrollTop

I can't see why this line was included, but I am only looking at it from my own scenario. If anyone can tell me why it's bad to NOT have this line (aside from "don't hack plugins, you can overwrite them when you upgrade!"), feel free to let me know :)

EDIT:
An alternative to hacking the plugin code, I set up my affix like this:

var margin = 40;
var t = pageHeader.offset().top + ph.outerHeight() - margin;
var b = siteFooter.outerHeight() + margin;

myElement.affix({
      offset: {
         top: function () {
             return t;
         }
         , bottom: function () {
             return (myElement.hasClass("affix-top")) ? 0 : b;
         }
     }
});
@thegreyspot

This comment has been minimized.

Copy link

@thegreyspot thegreyspot commented Feb 27, 2014

The solution to this problem is VERY unclear. Everyone seems to have their own. Is there a way we can sum it up and push a fix or update the documentation?

@li5220008

This comment has been minimized.

Copy link

@li5220008 li5220008 commented Mar 12, 2014

var margin = 40;
var t = pageHeader.offset().top + ph.outerHeight() - margin;
var b = siteFooter.outerHeight() + margin;

myElement.affix({
offset: {
top: function () {
return t;
}
, bottom: function () {
return (myElement.hasClass("affix-top")) ? 0 : b;
}
}
});

@lukaszklis

This comment has been minimized.

Copy link

@lukaszklis lukaszklis commented Mar 13, 2014

In my case, parsing position.top helped: https://gist.github.com/lukaszklis/9528158#file-gistfile1-js-L11

@sirpengi

This comment has been minimized.

Copy link

@sirpengi sirpengi commented Mar 13, 2014

Re: #4647 (comment)
Modifying the bootstrap.js file by removing the line in CheckPosition fixed it for me. The alternative solution in that comment works only in cases where you scroll incrementally. Scrolling in large chunks (using pageup/pagedown) makes it set the wrong .affix class (that is, if you jump from .affix-top straight to somewhere below the (intended) bottom offset, it'll use 0 as the bottom.offset).

@HariantoAtWork

This comment has been minimized.

Copy link

@HariantoAtWork HariantoAtWork commented Mar 14, 2014

Soon I will fix this forever. My previous code got missing conditions. But
will work perfectly if the element is on top, not bottom.

§Harianto van Insulinde

On 14 mrt. 2014, at 00:36, "shu.chen" notifications@github.com wrote:

Re: #4647 (comment)#4647 (comment)
Modifying the bootstrap.js file by removing the line in CheckPosition fixed
it for me. The alternative solution in that comment works only in cases
where you scroll incrementally. Scrolling in large chunks (using
pageup/pagedown) makes it set the wrong .affix class (that is, if you jump
from .affix-top straight to somewhere below the (intended) bottom offset,
it'll use 0 as the bottom.offset).

Reply to this email directly or view it on
GitHubhttps://github.com//issues/4647#issuecomment-37600202
.

@thegreyspot

This comment has been minimized.

Copy link

@thegreyspot thegreyspot commented Apr 30, 2014

I dont understand why this is closed. I updated to the latest affix.js in github and I still have this issue. I have tried almost ALL of the suggested fixes, and it still jumpy when affix-bottom.

@cloudbring

This comment has been minimized.

Copy link

@cloudbring cloudbring commented May 1, 2014

I am having this issue as well, I say we re-open this issue and figure out a way to solve it.

@cvrebert

This comment has been minimized.

Copy link
Member

@cvrebert cvrebert commented May 1, 2014

@thegreyspot @cloudbring Feel free to file a new issue for this with a reproducible testcase. (And please use the latest code in the master branch when testing.)

@w0rp

This comment has been minimized.

Copy link

@w0rp w0rp commented Jun 1, 2014

I just ran into this issue also, or a least something like it. I was setting affix with a top and bottom offset set in data attributes. I resized my browser window down so there wasn't so much vertical space, and then moved the affix below the footer. It stopped perfectly where I asked it to. Then I scrolled back up and the affixed element warped right to the top of the page where it started and wouldn't budge again until I refreshed the browser.

@cvrebert

This comment has been minimized.

Copy link
Member

@cvrebert cvrebert commented Jun 1, 2014

@w0rp Perhaps you're running into #13111 or #13405? Otherwise, see my previous comment; we can't do anything unless you or someone else provides a testcase. Please provide one!

@robwent

This comment has been minimized.

Copy link

@robwent robwent commented Jun 4, 2014

Not sure if anyone has mentioned it but this is all dependant on browser height and the height at which the affix kicks in. That's why people can't replicate it as their browsers are not the same height.
If the affix kicks in as you get to the bottom of the screen then the page changes height and the affix gets removed again which keeps repeating so the page appears to jump.

@twbs twbs locked and limited conversation to collaborators Jun 10, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.