What is the best way to make a sticky floating sidebar that stays fixed while scrolling?

I'm facing a challenge on my website where I want a sidebar on the left to stay with the user as they scroll. The sidebar should scroll along with the user until it's 5px from the top of the page, at which point it should remain fixed in place.

In some cases, the viewport may be too small to fit the entire sidebar on the screen. This isn't a major issue, but I would like the sidebar to reach the footer of the page when the user scrolls to the bottom, and then scroll along with the page again.

I've included the code for my site and an attempt to achieve the first part of my question (although it's not currently working): jsfiddle.

The first part of the question should be clear, but the second part might be a bit confusing. Here's a mockup to help visualize it:

Here's the javascript code I've used for the first part:

$(document).ready(function () {
    var theLoc = 5;
    var links = $('#left');
    $(window).scroll(function () {
        console.log('scroll');
        if (theLoc >= $(window).scrollTop()) {
            if (links.hasClass('fixed')) {
                links.removeClass('fixed');
            }
        } else {
            if (!links.hasClass('fixed')) {
                links.addClass('fixed');
            }
        }
    });
});

It might also be a CSS issue:

.fixed {
    position: fixed;
}

I've tried adjusting the height, but it didn't seem to make a difference.

Answer №1

I tackled this problem a while back and came up with a solution. Here is the code snippet I used: Take a look at the JSFiddle.

(Keep in mind that you might need to adjust your HTML structure a bit. I recommend using divs and floating them to arrange your content. Alternatively, you can follow the code/logic provided below and create your own layout.)

Here's a basic overview:
- Obtain the necessary elements
- Determine the initial position of the sidebar upon page load
- Calculate #content.outerHeight()

With these variables set, during the window scroll event, check if we are either <= our original sidebarTop position or if we have surpassed the blogHeight. If either condition is met, remove the sticky class. Alternatively, if our scroll position is >= the original sidebar position, then add the .sticky class (which includes position: fixed).

Explore the JSFiddle (Click here)


The Javascript snippet is as follows:

// Store the fixed sidebar variables for scrolling functionality
var $sidebar = $('#sidebar-nav');

// Obtain and retain the initial position of #sidebar-nav for comparison
var sidebarTop = $sidebar.position().top;

// Adjust the `- 10` to control when it should disappear upon reaching the footer.
var blogHeight = $('#content').outerHeight() - 10;

// Bind the function below to the scroll event
$(window).scroll(fixSidebarOnScroll);

// The following function is called on window scroll (as bound above)
function fixSidebarOnScroll() {

    // Record our current scroll position
    var windowScrollTop = $(window).scrollTop();

    // Toggle the sticky class based on specific conditions
    if (windowScrollTop >= blogHeight || windowScrollTop <= sidebarTop) {
        $sidebar.removeClass('sticky');
    } else if (windowScrollTop >= sidebarTop) {
        if (!$sidebar.hasClass('sticky')) {
            $sidebar.addClass('sticky');
        }
    }
}

The HTML section:

<header>This is the header!</header>
<ul id="sidebar-nav" class="nav nav-list">
    <li><a href="#">Home</a></li>
    <li><a href="#">Blog</a></li>
</ul>
<div id="content">Content goes here. Scroll down to witness the sticky feature!</div>
<div class="clear"></div>
<div id="footer">This is the footer</div>

The CSS styles:

/* Fixate the navbar upon window scroll */
#sidebar-nav.sticky {position:fixed;top:5px;}

/* Additional styling for the HTML markup */
header {
    border:1px solid #aaa;
    background-color:yellow;
    margin-bottom:5px;
    height:50px;
}
#sidebar-nav {
    width:150px;
    border:1px solid #ddd;
    margin:0;
    padding:0;
    float:left;
}
#sidebar-nav li {
    list-style:none;
    border:1px solid #ddd;
    margin:10px;
    padding:2px;
}
#content {
    height:2000px;
    width:500px;
    padding:10px;
    border:1px solid #ddd;
    margin:0 0 10px 5px;
    float:right;
}
#footer {
    height:800px;
    border:1px solid green;
    background-color:#ddd;
}
.clear {
    clear:both;
}

:)

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

Displaying HTML5 video in Colorbox on an iPad device

Struggling to get HTML5 video tags to display properly through an inline Colorbox on the iPad. The jQuery code being used is: $(document).ready(function(){ $("#openColorbox").colorbox({ inline:true, width:"80%", height:"auto", href:"# ...

What are the potential drawbacks of importing a namespace and a child module together? For example, using `import React, { Component } from ...`

Collaborating with some colleagues on a React project, I began by importing React and constructing my class like this: import React from 'react' Class MyComponent extends React.Component But then they suggested that I also import Component sep ...

Display the component once the useEffect has been updated in React JS

I am currently working on developing a TV app and I am in need of creating a QR Code with a randomly generated code. This code should either be fetched from localStorage or generated on-the-fly if localStorage is empty. However, I am encountering an issue ...

Using the Mongoose $or operator with a nested array in query conditions

Here are the schemas I am using: //ProjectModel const ProjectSchema: Schema = new Schema( owner: { type: Schema.Types.ObjectId, ref: "User" }, users: [{type: Schema.Types.ObjectId, ref: "ProjectUser", unique: true }] ); //Project Use ...

Tips for incorporating Javascript in an innerHTML inline css situation

I'm just starting to learn about html5 and php. I'm curious about how to incorporate javascript into my existing code. Currently, I have data from a database displayed in an HTML table. My goal is to align the output of the last cell more toward ...

Leveraging the power of Angular.js to generate random user profiles

I am attempting to utilize the RUG (Random User Generator) API for a project, but I am struggling to make it function correctly. I have been trying to initiate an HTTP request after a click event, but unfortunately, it does not seem to be working as expect ...

Utilizing inline keyboard markup callbacks for sending messages to channels via a Telegram bot

When utilizing my Telegram bot to send messages to a channel, I also want to include an inline keyboard with each message. The layout of the keyboard should resemble this: inline message keyboard The challenge I am currently facing is figuring out how to ...

The header and footer are not extending across the entire width of the page

While testing on a responsive screen, I noticed that the header and footer both decrease in width instead of maintaining 100% width as intended. The issue only occurs when I reduce the width of the screen. body{ margin: 0; padding: 0; box-si ...

Plotting Data Points with Tags in React Native

After doing some research, I came across a few React Native packages that offer scatter plots such as react-native-scatter-chart, react-native-chart-kit, and react-native-chartjs. However, I am interested in finding something more customizable. I'm s ...

Change the position of an HTML image when the window size is adjusted

My web page features a striking design with a white background and a tilted black line cutting across. The main attraction is an image of a red ball that I want to stay perfectly aligned with the line as the window is resized, just like in the provided gif ...

Attempting to update information in JSON using AJAX and PHP

I am attempting to update key values in a JSON object using PHP, AJAX, and JavaScript to display the new values. Here is an example of my JSON database that needs to be modified: "answer01count": "1", "answer02count": "2", "answer03count": " ...

Discovering how to identify words separated by spaces within a full-text search query using regex in both PHP and JavaScript

When working with text, I need to detect words that are separated by spaces. For example, if my text is: some parent +kid -control "human right" world I want to only detect some, parent, and world. This means words without any special characters like +, ...

What is the best way to set the length of an undefined item in an object to 0 in reactjs?

I am facing a challenge keeping track of scores within each article and displaying them accurately. The issue arises when there is a missing "up" or "down" item in the object. Below is the data containing all the votes: const votes = { "1": { "up": ...

Convert the button element to an image

Can someone please explain how to dynamically change a button element into an image using javascript when it is clicked? For instance, changing a "Submit" button into an image of a check mark. ...

Can values be extracted from a JSON object that is saved in a separate JavaScript file?

In my current project, I am creating unique tables dynamically and displaying them using JavaScript after making an AJAX call. Instead of writing individual code for each table, I'm looking to establish a standard layout where I can customize the desi ...

I am looking to develop a unique event that can be triggered by any component and listened to by any other component within my Angular 7 application

Looking to create a unique event that can be triggered from any component and listened to by any other component within my Angular 7 app. Imagine having one component with a button that, when clicked, triggers the custom event along with some data. Then, ...

Is there a way to display a vertical list in a horizontal orientation?

I am in the process of creating my portfolio on Cargo Collective and have customized one of their pre-made themes to suit my preferences. The only thing I'm currently struggling with is how to change a set of vertical links to display horizontally ins ...

What is the best way to generate an array containing multiple arrays, each filled with dynamic Divs?

I have the following code that displays a Div when the user clicks on the Add button. For example, if the user clicks the Add button 5 times, then 5 will be displayed with the same controls/inputs under default. html <div ng-repeat="st in stu"> ...

Using Rails and Haml to Implement Smooth Scrolling with Jquery and CoffeeScript

Looking to accomplish a straightforward task using CoffeeScript, Rails, and Haml. While I don't have much experience with CoffeeScript, I'm eager to experiment. The goal is to have the view scroll to a specific div id when a button is pressed. A ...

Scraping a JavaScript page using Python without requiring a browser installation

Currently, I am facing a challenge in scraping an HTML element from a webpage. The content within this element is dynamically generated by Javascript, making it impossible to retrieve using a simple requests.GET: response = requests.get(url). While explor ...