Tips on creating a stationary sidebar that ends at the container's edge

I currently have a container set up with two columns, where one column acts as a sidebar.

JSFiddle

The sidebar is positioned as fixed, and I've utilized jQuery to adjust the bottom property so that it roughly stays at the bottom of the container as you scroll.

Is there a way to make the sidebar stop moving precisely when it reaches the bottom edge of the container (which is marked in red)? This solution should be able to handle sidebars of varying heights.

HTML

<div class="container">
      <div class="col-left">
        <div class="sidebar">
          Fixed sidebar content
        </div>
      </div>

      <div class="col-right">
        <p>Paragraph</p>
        <p>Paragraph</p>
        <p>Paragraph</p>
      </div>
    </div>

    <footer>Footer</footer>
    

CSS

.container {
      outline: 1px solid red;
      position: relative;
    }

    .col-left {
      width: 58%;
      display: inline-block;
      outline: 1px solid black;
      vertical-align: top;
      height: 100%;
    }

    .col-right {
      width: 40%;
      display: inline-block;
      outline: 1px solid black;
      vertical-align: top;
    }

    .sidebar {
      position: fixed;
      top: 50px;
      left: 50px;
      height: 200px;
      width: 100px;
      background: #fff;
    }

    footer {
      background: #000;
      width: 100%;
      height: 300px;
      margin-top: 100px;
      color: #fff;
    }
    

jQuery (I suspect this code may need reevaluation)

jQuery(window).scroll(function(){
      var scrollBottom = jQuery(document).height() - jQuery(this).scrollTop() - jQuery(this).height();
      console.log(scrollBottom);

         if (scrollBottom < 300){
             jQuery('.sidebar').css('bottom', Math.abs(scrollBottom - 420));
           jQuery('.sidebar').css('top', 'auto');
         } else {
           jQuery('.sidebar').css('bottom', 'auto');
           jQuery('.sidebar').css('top', '50px');
         }
    

Answer №1

Utilizing jQuery, this solution involves calculating heights of specific elements and taking into account the current scroll position on the page. When the sidebar would exceed its container, a .lock class is applied to ensure it stays within bounds using CSS.

See the working example below:

var $sidebar = $('.sidebar');
var $container = $('.container');
var sideBottom = $sidebar.offset().top + $sidebar.height();
var contBottom = $container.offset().top + $container.height();

$(window).scroll(function() {
  if (window.scrollY + sideBottom > contBottom) {
    $sidebar.addClass('lock');
  } else if ($sidebar.hasClass('lock')) {
    $sidebar.removeClass('lock');
  }
});
body {
  background: #eee;
  margin: 0;
}

.container {
  outline: 1px solid red;
  position: relative;
}

.col-left {
  width: 58%;
  display: inline-block;
  outline: 1px solid black;
  vertical-align: top;
  height: 100%;
}

.col-right {
  width: 40%;
  display: inline-block;
  outline: 1px solid black;
  vertical-align: top;
}

.sidebar {
  position: fixed;
  top: 50px;
  left: 50px;
  height: 140px;
  width: 100px;
  background: #fff;
}

.sidebar.lock {
  position: absolute;
  bottom: 0;
  top: auto;
}

footer {
  background: #000;
  width: 100%;
  height: 400px;
  margin-top: 100px;
  color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="container">
  <div class="col-left">
    <div class="sidebar">
      fixed sidebar
    </div>
  </div>

  <div class="col-right">
    <p>Paragraph</p>
    <p>Paragraph</p>
    <p>Paragraph</p>
    <p>Paragraph</p>
    <p>Paragraph</p>
    <p>Paragraph</p>
    <p>Paragraph</p>
    <p>Paragraph</p>
    <p>Paragraph</p>
    <p>Paragraph</p>
    <p>Paragraph</p>
  </div>
</div>

<footer>Footer</footer>

Answer №2

Give this a shot, it could make a difference.

.sidebar{
  position: -webkit-sticky;
  position: sticky;
  top: 0;
}

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

Opacity is causing issues with hover effects in CSS

I'm facing an unusual CSS challenge. Check out this simple code snippet below that showcases the issue: <html> <head> <style> .hover { float: right; } .hover:hover { background-color: blue; ...

Notification system for managing recurring tasks

Situation I am currently working on an application where users are assigned daily tasks such as "wash the window, clean the floor," and so on. Each task has a specific recurrence interval and must be completed at least once within that time frame. For e ...

Combining duplicate values in MongoDB using aggregation

In my code, I have an aggregate function that counts the occurrences of a value in the database: let data: any = await this.dataModel.aggregate( [ { $match: { field: new ObjectID(fieldID), }, }, ...

Unusual SVG Cubic Bezier Animation Transforming Curves into Points and Lines

As a beginner in SVG CSS animation, I am currently working on morphing three curved paths into three rectangles using cubic bezier routes. While I have managed to make it work, there is an issue during the transition where parts of it skew inward in a stra ...

Replicate the form to a new one while concealing the elements and then submit it

Initially, I was working with just one form. Now, I find myself in a situation where I need to utilize a different form which contains the same inputs. This is necessary because depending on the action taken upon submission, different processes will be tri ...

The angular 5 application encountered an issue where it was unable to access the property 'singlePost' due to a null value, resulting

When using the once method to fetch data from the Firebase database, everything works correctly. However, when I try to use the on method, I encounter an error that says: ERROR TypeError: Cannot read property 'singlePost' of null. How can I prope ...

Create a sleek design by aligning labels with CSS 3 fancy radio buttons

I have a radio button with a larger circle that needs to be 38px input[type=radio] { visibility: hidden; } .label { font-weight: normal; color: #333; } .label::before { content: ''; position: absolute; left: 0; w ...

What is the best way to eliminate an element from a state using the useState hook?

I need help with generating a list of values from checkboxes. const [checkedState, setCheckedState] = useState({}); const handleOnChange = (e) => { if(e.target.checked === true){ setCheckedState({ ...checkedState, [e.target.name]: e.target.checke ...

What is the best way to substitute </br> and <br/> with in a text?

Is there a way to replace </br> and <br/> with \n functionally? There seems to be varied responses to this query. Errors are often made when writing the break tag. The solutions for both types of breaks mentioned above are detailed below ...

Creating these three functions directly in the Parent Component instead of duplicating code in the child component - ReactJS

I am new to React and currently working on a dashboard page that includes a React Table. The page features a customize button that opens a popup with checkboxes to show/hide columns in the table. By default, all checkboxes are checked but unchecking a colu ...

Cannot submit form data from HTML to PHP

I am having trouble passing data from an HTML form to a PHP page. The form data is not being submitted successfully. Can anyone point out what mistake I might be making? HTML FORM <div id="go"> <form method="get" action="client_authorized.ph ...

Guide to altering the color of the row that is clicked in a table using css and jquery

Is there a way to change the text color of a row in a table when it is clicked, similar to an example like this but without changing the background color? The code I have tried is not working for me. Below is a snippet of the code I am using: $("#myTab ...

Repetitive points detected in three.js typography

I converted a ttf font to a js font for three.js using Facetype.js, but I am encountering multiple duplicate point errors such as: THREE.Shape: Duplicate point 41.52:10.928 THREE.ShapeUtils: Unable to triangulate polygon! in triangulate() What steps ...

Ways to restrict HTML styling to just the header section and avoid affecting the entire webpage

As a newcomer to HTML, please excuse my lack of knowledge. I am struggling to keep my current design at the top of my page, similar to a fixed header that follows the user down the page. Currently, the design takes over the entire page, obscuring the bod ...

Enhance your Vue 3 experience by optimizing URL parameters for easy bookmarking and efficient filtering

I am eager to enhance my application by adding URL parameter functionality: When a filter is applied, the URL should be updated automatically If someone accesses the URL directly, they should see the same filtered data I have observed various approaches ...

Using Vue's v-if statement to determine if a variable is either empty or null

Using a v-if statement to display certain HTML only if the archiveNote variable is not empty or null. <div v-if="archiveNote === null || archiveNote ===''" class="form-check ml-3" id="include-note-div"> Here is how it's implemented ...

Guide on how to have two controllers execute identical tasks in Angular while modifying the appearance of the website

Trying to recreate Google's homepage functionality using Angular has been challenging for me. Despite watching Egghead videos and studying the API extensively, I couldn't find a specific example for this behavior. Here's what I aim to achiev ...

Receive fresh properties in React and subsequently reset state

I need some guidance on this issue: My scenario involves a parent React component and its child. The parent component contains a table, while the child has its own controls. What I am trying to achieve is the ability to click on a cell within the parent&a ...

SonarQube flagging a suggestion to "eliminate this unnecessary assignment to a local variable"

Why am I encountering an error with SonarQube? How can I resolve it since the rule page does not offer a specific solution? The suggestion is to eliminate the unnecessary assignment to the local variable "validateAddressRequest". validateAddress() { ...

Improving communication between Components in ReactJS

I am attempting to update the state from one component to another component. I wish for the state total on header.jsx to be updated when I click on the add to cart button on product.jsx Below is my code: index.jsx // Code for index.jsx goes here head ...