jQuery Sticky (Fixed Position) Sidebar with Bootstrap 3 col-push Problem

The Issue

It works on desktop browsers, but not iPad or Safari

Using jQuery Sticky and Bootstrap 3, a “stuck” sidebar should stay at the defined distance from the top and in the exact place it started to the left/right. However, when using Bootstrap’s column push and pull, a Sticky sidebar breaks.

On the iPad, the sidebar jumps to the opposite side of the screen. If you are on an iPad 2 (and maybe other versions) or Safari 5 for Windows (and maybe other versions) you should see the issue happening as you scroll down.

Problem Demonstrated Example

Problem Fixed Example

Details

I’ve liked using the jQuery Sticky plugin for any sites I develop that call for a sticky sidebar or header/menu. It is super-simple and effective. So, I was suprised when I recently discovered that it wasn’t working as expected on my iPad 2 or on Safari for Windows (I don’t have a Mac to test out the latest version of Safari). The only time it had an issue was when I had rearranged columns using Bootstrap 3’s column push and pull classes. Whenever I used these, the area I made sticky jumps from within the sidebar column I created using “col-md-3 col-md-pull-9”, to the far right side of the row, as if I had only used “col-md-3” without pulling it back left.

The problem seems to only present when there is a rearranged column order using col-md-push and col-md-pull, like:


<div class="row">
<div class="col-md-9 col-md-push-3">
...some content
</div>
<div class="col-md-3 col-md-pull-9">
<div id="stick-container">
...sidebar stuff that jumps from left side to right side on iPad.
</div>
</div>
</div>

Using Safari’s developer tools menu, it appears that the Bootstrap components are not the issue. The “.col-md-3” that I pulled right stays in place. The “#sidebar-sticky-wrapper” element also stays put. However, the “#sidebar” element to which the Sticky is applied breaks out of those two boxes and appears on the right side of the row, as if its new applied “fixed” positioning is not inheriting the proper “left” or “right” positioning.

Confirmed incorrect, unexpected behavior on:

  • Safari 5.1.7 for Windows
  • iPad 2

However, everything works as expected when using “typical” column order like:


<div class="row">
<div class="col-md-9">
...some content
</div>
<div class="col-md-3">
<div id="stick-container">
...sidebar stuff that works everywhere.
</div>
</div>
</div>

Confirmed correct, expected behavior on:

  • Chrome
  • Chrome Developer Tools iPad device mode
  • IE 8
  • IE 9
  • IE 10
  • IE 11
  • Edge
  • Firefox

The Fix

Because the issue seems to be based on the Sticky element breaking out of its parent container, which is caused by the application of the “fixed” positioning, I focused on testing combinations of positioning for those parent elements to contain it.

In the end, applying a “relative” position to the parent “.row” and “absolute” positioning to the parent “.col-md-3 col-md-pull-9” fixed the issue while keeping it working in all the other browsers. I don’t know why exactly, but it works. Keep in mind that you need to limit the scope of this to only when “Sticky” is applied, otherwise when the Bootrap columns shift, your absolutely positioned element will likely breaking your flow. In this specific case, it meant using a media query at the default “md” break, 992px.

My Solution

Here is the issue fixed.


@media(min-width: 992px){
#main .row{
position:relative;
}
#main .col-md-pull-9{
position:absolute;
}
}

There are likely more elegant solutions for this–and certainly better explained–but this is what I found after a haphazard poke-and-check methodolgy.

Comments

  1. Worked for me! Thanks.
    Applied in to ajoomla site with template T3 BS3 Blank from joomart.
    Modified file in templates/t3_bs3_blank/tpls/blocks/mainbody/one-sidebar-left.php

    hasMessage()) : ?>



    <div class="t3-sidebar t3-sidebar-left col-xs-12 col-sm-2 col-sm-pull-10 col-md-2 col-md-pull-10 _c($vars[‘sidebar’]) ?>” style=”position: absolute;”>
    <jdoc:include type="modules" name="_p($vars[‘sidebar’]) ?>” style=”T3Xhtml” />

  2. Seems the fixed example is not working for me. Chrome 48.0

  3. Not working in FF or Safari