Creating a sticky menu in a column using affix with a CSS bootstrap list-group

My goal is to develop a sticky menu utilizing CSS Bootstrap affix and the list-group menu.

I have successfully implemented most of it, except for one issue when the user scrolls down.

Upon scrolling down, the menu expands to fill the entire width of the page.

I attempted to set it up using data attributes like so:

Here is an example of my code:

<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 lengthy content for the body along with tables.

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

However, the data attribute did not achieve the desired sticky effect; instead, it remained fixed at the top.

To address this issue, I tried incorporating JavaScript to fix the problem:

$(function(){

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

});

I have included a jsFiddle link to showcase the current behavior.

What steps can I take to ensure that the affix functionality maintains the menu's shape as the user scrolls down?

Answer №1

To begin with, it is recommended to utilize either data-attributes or JavaScript.

I have made adjustments to your jsFiddle. The position of id="leftCol" has been modified:

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

        <div id="leftCol">

              ...

        </div>

    </div>

Additional styling has been applied:

#leftCol {
   width: 220px;
}

Furthermore, media queries should be incorporated to eliminate affix for mobile view.

Answer №2

Instead of resorting to an "unacceptable" hack, I decided to set a maximum width for the menu at 250px like shown below:

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

I couldn't figure out how to make it work without explicitly specifying a max-width, which should ideally be inherited from the parent element with the class col-md-3.

UPDATE

Luckily, javascript came to the rescue!

I implemented the following JS solution to tackle this issue once and for all.

This script dynamically resizes the menu whenever the affix.bs.affix event is triggered.

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

Refer to the documentation for more details.

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

Answer №3

After making some adjustments, it looks like the code is now functioning as desired. The key modifications I implemented included incorporating the following 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;
}

I also restructured certain aspects of your HTML:

<div class="container body-content">
    <div>Here is some placeholder content to allow for more scroll before the navigation becomes fixed. You will need to set the height in data-offset-top in the leftCol DIV below this content. This same principle applies if you want to set 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">
             *your remaining code*
            </div>
        </div>
    </div>
</div>

One issue remains with the sticky navigation menu being of variable height. As you scroll, the content underneath jumps up and gets concealed. It appears that addressing this may require JavaScript, as discussed in this Stack Overflow post.

Here's the updated Fiddle link for your reference: Updated Fiddle Link. I hope this resolves any lingering concerns.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Are you interested in creating dynamic tables/models with Sequelize?

Currently, I am exploring a theoretical question before diving into the implementation phase. The scenario is as follows: In my application, users have the ability to upload structured data such as Excel, CSV files, and more. Based on specific requirement ...

Converting Laravel variable into an image using JavaScript

I have a base64 string that I'm passing from the controller to the view. After verifying that the base64 string is correct online (by converting it to an image), I am attempting to call it in my JavaScript like so: <script> var crosshairImg ...

In React, the constant always has a default value of "Object : Default"

My current project involves using SlateJS and I am encountering an issue when trying to load data into a const using: imgData = data.get("file"); Everything works as expected if React is not imported, but once it is included, the object contains unexpecte ...

javascript The event handler is not functioning properly for the dynamically loaded AJAX content

I am facing an issue with adding a JavaScript event listener to a dynamically loaded div via AJAX. Below is my code snippet: var QuantityMiniCart = function() { var infor = document.querySelectorAll( '.mini-cart-product-infor' ); if ( ...

Creating a factory class in Typescript that incorporates advanced logic

I have come across an issue with my TypeScript class that inherits another one. I am trying to create a factory class that can generate objects of either type based on simple logic, but it seems to be malfunctioning. Here is the basic Customer class: cla ...

What could be the reason for the page scrolling upwards when clicking on href="#"?

I am encountering an issue with a hyperlink <a href="#" id="someID">Link</a> that is located further down the page. This link is used to trigger an Ajax request, but whenever it is clicked, the page automatically scrolls back to the top. I have ...

Position a div at the bottom of another div using Bootstrap

I'm facing an issue with trying to position an inner div at the bottom of an outer div using bootstrap classes. I have attempted various methods in both bootstrap and regular CSS, such as vertical-align: bottom; and setting position to absolute, but n ...

How does React retain and display the previous values even after they have been updated?

https://codesandbox.io/s/objective-night-tln1w?file=/src/App.js After updating the data in the dropdown, the console displays the correct values. However, the dropdown itself continues to show the previous values. It seems that there may be an error relat ...

Issue with Vue JS function not providing the desired array output

I declared a property in my data model like this: someArray: [] A function returns an array: getMyArray: function (someId) { var result = [7, 8, 9, 10]; return result; } I'm assigning the result of the function to m ...

Setting the flex-direction for <td> elements: A helpful guide

This is a snippet from the render function of one of my components, showcasing a table: return ( ... <td> <div style={{ width: '100%' }}>50</div> {' '} <span clas ...

The primary view seamlessly integrates with the page following the invocation of the partial view

Whenever the button is clicked, a different partial view is returned based on the selected value from the drop-down list. Controller: [HttpPost] public ActionResult Foo(SomeViewModel VM) { var model = VM; if (Request.IsAjaxRequest()) { ...

Imitation of three-dimensional camera rotation

I've been exploring the realm of creating 3D games using JavaScript and HTML's 2D canvas. I recently came across a helpful tutorial that guided me in setting up a basic interactive scene. Now, I'm facing a challenge in implementing the func ...

What could be the reason for this code not waiting for module imports?

Currently, I am facing an issue with dynamically importing modules in a nodejs server running in the development environment. To achieve this, I have implemented an immediately-invoked async function which, in theory, should work perfectly. However, it see ...

Issue with the height of sections in the active menu

While the set-up below is functional for content within section height limits, it fails when exceeding the limit causing overflow. Adding "display: table" or "overflow: hidden" to fix the overflow issue affects the menu's active state behavior. Sett ...

How big should the placeholder image be for the image area?

How can I create a loading image to replace a .gif while it loads? I need a placeholder image of about 325x325 (same size as the gif) to keep content in place. I've attempted using background: url() without success and haven't explored JS/jQuery ...

Having trouble with missing jQuery form serialize data in CodeIgniter when using TinyMCE?

I have encountered an issue while using tinymce. I am sending data through a jQuery ajax call like this: // update textarea from tinymce tinyMCE.triggerSave (false,true); $.post ('', $('#page_form').serialize (), function (x){ var ...

One way to dynamically hide certain fields based on the value of another field is by utilizing AngularJS, Razor, and C# in

Need assistance with AngularJS and Razor. I am a beginner in these technologies and need some help with the following code snippet: <div ng-app=""> <p>Input page number to filter: <input type="text" ng-model="pageNumber"></p> ...

Encountered an issue following deployment to Heroku (Application error)

Introduction I recently created a Login form for my project. The frontend is deployed on Netlify at this link, and the backend is hosted on Heroku which can be accessed here. To view the backend logs, click here Here is a snippet of my index.js file: co ...

Establishing a variable to serve as a function invocation

Is there a way I can assign a variable to either .prev() or .next()? Here is an example of what I am trying to do: if(x == y) var shift = '.prev()'; else var shift = '.next()'; $("li.active").removeClass('a ...

JavaScript is a powerful tool for reading JSON files

I'm trying to figure out how to parse a nested object in JSON using JavaScript. Here's the code I have so far: var myRequest = new Request('test.json'); fetch(myRequest) .then(function(response) { return response.json(); }) .then( ...