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

Affix not working correctly with column reordering #12126

Closed
MysticEarth opened this Issue Jan 6, 2014 · 14 comments

Comments

Projects
None yet
@MysticEarth

MysticEarth commented Jan 6, 2014

When using column reordering and using the affix-plugin on an element positioned with push, the affix plugin doesn't work correctly - the element affected by the affix plugin is positioned to the left even when the element is in a column positioned on the right.

Used without column reordering, it does work correctly.

See http://jsbin.com/eCoQIWat/1/ for reproduction of the issue.

@mdo

This comment has been minimized.

Member

mdo commented Jan 6, 2014

Yeah the mixed positioning of column reordering with the affix is broken. We could benefit from more flexible positioning.

@deviprsd

This comment has been minimized.

deviprsd commented Jan 6, 2014

Same problem .... i added position: fixed to it ...

@fat

This comment has been minimized.

Member

fat commented May 13, 2014

affix plugin just swaps classes, it doesn't do anythign with styles, afaik.

So if im understanding you correctly, to get around this you'd just have to make sure that you are styling the classes applied appropriately.

@fat fat closed this May 13, 2014

@mdo mdo removed this from the v3.2.1 milestone May 13, 2014

@mdo mdo added css and removed js labels May 13, 2014

@chood531

This comment has been minimized.

chood531 commented Jul 11, 2014

@fat - this issue should be re-opened.

Using push and pull moves your columns using relative positioning.

Even if you have the correct classes set for affix, the issue in Safari is that the "affixed" element does not inherit the relative positioning that is applied to the column. Therefore, the affixed element is not pushed or pulled in the right place when the fixed positioning is applied.

As a result, the affixed element is put in the original position where the column would have been if you did not push or pull it.

You can see an example of this here: http://blog.automatedself.com

I am only able to replicate the issue in Safari. It does not appear to be an issue in Chrome or Firefox.

@chood531

This comment has been minimized.

chood531 commented Jul 11, 2014

My hack fix for this is to check the distance from the left of the screen right before the affix happens. Looks something like this:

/* Check if we are in safari */
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {

        /* Before the element becomes affixed, add left CSS that is equal to the distance of the element from the left of the screen */
        $('#sticky-widget-1').on('affix.bs.affix',function(){
            $('#sticky-widget-1').css('left',$('#sticky-widget-1').offset().left+'px');
        });


    }
@dxinteractive

This comment has been minimized.

dxinteractive commented Jul 15, 2014

^ I'll expand on the above hack - with fluid layouts it sets the horizontal position but doesn't update it if the window resizes. The following fixes that:

/* Check if we are in safari */
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
    var stickywidget = $('#sticky-widget-1');
    var explicitlySetAffixPosition = function() {
        stickywidget.css('left',stickywidget.offset().left+'px');
    };
    /* Before the element becomes affixed, add left CSS that is equal to the distance of the element from the left of the screen */
    stickywidget.on('affix.bs.affix',function(){
        explicitlySetAffixPosition();
    });

    /* On resize of window, un-affix affixed widget to measure where it should be located, set the left CSS accordingly, re-affix it */
    $(window).resize(function(){
        if(stickywidget.hasClass('affix')) {
            stickywidget.removeClass('affix');
            explicitlySetAffixPosition();
            stickywidget.addClass('affix');
        }
    });
}

Lets hope this is fixed natively soon.

@EricJammin

This comment has been minimized.

EricJammin commented Aug 21, 2014

@fat this issue should definitely be re-opened.

In fact, if you apply the push and pull classes on the 2 columns of any of the bootstrap doc pages, you will see the affix clearly breaks in Safari. The affixed element contained inside the pushed column does not respect it's positioning. Only in Safari.

Here it is at top of page (normal):
bs-affix_safari-top

And now after scrolling past threshold where element becomes fixed:
bs-affix_safari-scroll

@randomnerd

This comment has been minimized.

randomnerd commented Dec 2, 2014

+1 for reopening.

Thanks for sharing a workaround anyway. I will just leave a CoffeeScript variant here :)

safariFix = (elemId) ->
  # Check if we are in safari
  return unless navigator.userAgent.indexOf('Safari') != -1
  return unless navigator.userAgent.indexOf('Chrome') == -1

  stickywidget = $(elemId)
  explicitlySetAffixPosition = ->
    stickywidget.css 'left', stickywidget.offset().left + 'px'

  # Before the element becomes affixed, add left CSS that is
  # equal to the distance of the element from the left of the screen
  stickywidget.on 'affix.bs.affix', -> explicitlySetAffixPosition()

  # On resize of window, un-affix affixed widget to measure where
  # it should be located, set the left CSS accordingly, re-affix it
  $(window).resize ->
    return unless stickywidget.hasClass 'affix'
    stickywidget.removeClass 'affix'
    explicitlySetAffixPosition()
    stickywidget.addClass 'affix'
@ajbarry

This comment has been minimized.

ajbarry commented Dec 5, 2014

+1 for reopening

@coltonbrugger

This comment has been minimized.

coltonbrugger commented Dec 5, 2014

+1 for reopening

Affixed nav in sidebar on (quite typically) pushed/pulled main+sidebar layout breaks in Safari.

@gpakosz

This comment has been minimized.

Contributor

gpakosz commented Dec 18, 2014

Got bitten. Please reopen even if there's no clean css only fix.

@browniebroke

This comment has been minimized.

browniebroke commented Feb 4, 2015

I had the problem, and applied @dxinteractive workaround, but there was a corner case when scrolling all the way to the bottom, where affix-bottom was applied, and then scrolling back up. I think this triggers affix.bs.affix again, which -I think- leads the affixed element to be completely out the frame (might be related to the inline "position:relative" left in this use case, ref #15668), since the left is doubled at this point.

I've improved the workaround by resetting the left property to 0 when affix-bottom.bs.affix fires. Not sure if that's a universal better solution, but it worked for me so I thought I'd share it:

/* Check if we are in safari: */
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
    var stickywidget = $('#sticky-widget-1');
    var explicitlySetAffixPosition = function() {
      stickywidget.css('left', stickywidget.offset().left+'px');
    };
    var resetLeftPosition = function() {
      /* Adapt the left property to your element's value before any affix behavior */
      stickywidget.css('left', '0px');
    };
    /* Before the element becomes affixed, add left CSS that is equal to the distance of the element from the left of the screen */
    stickywidget.on('affix.bs.affix', function(){
      explicitlySetAffixPosition();
    });
    /* Before the element becomes affix-bottom, reset the CSS left property to as it was before */
    stickywidget.on('affix-bottom.bs.affix', function(){
      resetLeftPosition();
    });
    /* Do the same for affix-top */
    stickywidget.on('affix-top.bs.affix', function(){
      resetLeftPosition();
    });

    /* On resize of window, un-affix affixed widget to measure where it should be located, set the left CSS accordingly, re-affix it */
    $(window).resize(function(){
      if(stickywidget.hasClass('affix')) {
        stickywidget.removeClass('affix');
        explicitlySetAffixPosition();
        stickywidget.addClass('affix');
      } else if (stickywidget.hasClass('affix-bottom')){
        resetLeftPosition();
      }
    });
}

JoshData added a commit to if-then-fund/if.then.fund that referenced this issue Apr 14, 2015

page-section-nav: bootstrap affix doesn't work in pushed/pulled colum…
…ns in Safari, and the width isn't right anywhere

twbs/bootstrap#12126 / twbs/bootstrap#16282

Reverse the columns so there is no pushing/pulling. Set the width in Javascript, or else the nav extends into the other column.
@michel-kraemer

This comment has been minimized.

michel-kraemer commented Apr 22, 2015

+1 for reopening

michel-kraemer added a commit to michel-kraemer/vertx-web-site that referenced this issue Apr 22, 2015

@cvrebert

This comment has been minimized.

Member

cvrebert commented Apr 23, 2015

Locking this since #16282 has now documented the limitation / Safari-bug, and since trying to workaround/fix this won't be on the Core Team's todo list given our plans for Bootstrap v4 regarding the Affix plugin.

That said, if anyone has a sane-ish workaround/fix they'd like to propose for v3, feel free to open a pull request.

Also, Protip: Odds are that nobody on the Core Team is still subscribed to old closed issues, so comments/pleas on them will most likely go unheard; you're better off opening new issues instead.

@twbs twbs locked and limited conversation to collaborators Apr 23, 2015

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.