7

I am trying to create a sticky menu using CSS Bootstrap affix and list-group menu.

I manage to get most of it to work except for when the user scrolls down.

When the user scrolls down, the menu seems to take the entire with of the page.

I tried to set it up via data attributes

using something like this

<div class="container">
    <div class="row">
        <div class="col-md-3" id="leftCol">

            <div data-spy="affix">

                <div class="list-group list-group-root well">
                    <a class="list-group-item" href="#introduction">Introduction</a>
                    <a class="list-group-item" href="#features">Features</a>
                    <a class="list-group-item" href="#dependencies">Dependencies</a>
                </div>

            </div>

        </div>
        <div class="col-md-9" id="mainCol">

            Some long text for the body along with some tables.

        </div>
    </div>
</div>

But the data attribute did not make the menu stick! it just kept it on the top.

So I tried to use JS to get the job done like this

$(function(){

    $('#leftCol').affix({
      offset: {
        top: 100,
        bottom: function () {
          return (this.bottom = $('.footer').outerHeight(true))
        }
      }
    });


});

I created jsFiddle to show you the current behavior.

How can I fix this affix so when the user scrolls down the menu maintain the same shape?

Junior
  • 11,602
  • 27
  • 106
  • 212

3 Answers3

2

First of all, you should use either data-attributes or JS.

I updated your jsFiddle. The position of id="leftCol" was changed:

<div class="col-md-3" >

        <div id="leftCol">

              ...

        </div>

    </div>

and style was added:

#leftCol {
   width: 220px;
}

Also, you should add media queries to remove affix from mobile view.

Evgeny Kuznetsov
  • 2,132
  • 2
  • 17
  • 27
  • 1
    I removed data-attributes and used only JS. – Evgeny Kuznetsov Dec 29 '16 at 19:24
  • Thats what I have done too. But why would I have to add fix or max width to the container? it is wrapped with a `col-md-3` class which should control the width of the menu to work on any devise. – Junior Dec 29 '16 at 19:26
  • What's the purpose of the width: 200px? It is already inside a col-md-3. Also I still have the same problems with the JSFIddle you linked – Mese Dec 30 '16 at 07:17
  • 1
    "In both situations, you must provide CSS for the positioning and width of your affixed content." [http://getbootstrap.com/javascript/#affix] (bootstrap documentation). – Evgeny Kuznetsov Dec 30 '16 at 07:25
1

As an "unacceptable" workaround, I set a max width of the menu to 250px like so

.list-group.list-group-root {
    padding: 0;
    max-width: 250px;
}

I am not sure how to get it to work without adding a max-with the max with should be defined by the parent. In this case class="col-md-3"

UPDATED

javascript to the rescue!

I added the following JS code to solve this problem once an for all.

It basically resize the menu everytime affix.bs.affix event is fired

$(document).on('affix.bs.affix', '#docs-menu', function() {
    $(this).width($(this).width());
});

From the docs

affix.bs.affix => This event fires immediately before the element has been affixed.

Junior
  • 11,602
  • 27
  • 106
  • 212
0

Ok I believe I got most of the code working like you want it to. The main changes I made were adding this CSS:

#leftCol {
    display: block;
    height: auto;
    padding: 0;
    width: 100%;
}

.navbar-fixed-top-again {
    position: static;
    top: 60px;
    z-index:1031;
}
.navbar-inner {
    background: red;
    padding: 5px;
}

.affix {
    position: fixed !important;
}

and I changed up some of the structure on your HTML:

<div class="container body-content">
    <div>made up content to allow the navigation to scroll more before it becomes sticky. This height will need to be set in the data-offset-top which is in the leftCol DIV just below this content. The same will apply if you need to set it for a footer offset.</div>

    <!-- new nav section -->
    <div class="col-md-3 navbar-fixed-top-again" id="leftCol" data-spy="affix" data-offset-top="80">
        <div class="navbar-inner">
            <div class="list-group list-group-root well">
             *the rest of your code*
            </div>
        </div>
    </div>
</div>

The main problem now is having a sticky navigation menu with variable height. If you notice when you scroll your reading content underneath jumps up and gets hidden. It seems that it is possible to fix this using JavaScript (link to SO question).

Heres the link to your updated Fiddle. Hope that helps.

Community
  • 1
  • 1
crazymatt
  • 3,266
  • 1
  • 25
  • 41