Farbod Salamat-Zadeh
Farbod Salamat-Zadeh

Reputation: 20120

Fixed layout positions in CSS only as it scrolls up (snap to top)

I am not sure if there is a specific name for the behaviour I want to achieve (in the title).

I'll give an example: on the issues pages on GitHub (e.g. here), where the right column (with information about labels, milestones, assignees) has a fixed position, but only when you scroll down. In other words, it seems to have a static layout as you are scrolling it at first, but then snaps to the top and acts like a fixed layout as you scroll further.

Another example would be how the left and right columns (navigation and contents) on some Google Developer documentation behave in a similar way I have described above.

I hope my question isn't too vague, and although I am aware of position: fixed; in CSS, I am unsure of how to adapt it to achieve the desired effects above.

Upvotes: 0

Views: 555

Answers (2)

Steve K
Steve K

Reputation: 9055

You can do this by adding and removing classes on scroll with Jquery or javascript I am using jquery here. Also in the following example I added a class to stop the sidebar when it hits the footer but if you just want it to keep going you can remove that part and just keep the sidebar scrolling.

Here is a fiddle Fiddle Demo

I have put this in a full html page so you can just copy and paste it into your text editor so you can see it in action.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <style>
    body{padding: 0;margin: 0;color:#fff;}
    header{background: blue;height: 100px;text-align: center;}
    footer{background: blue;height: 1000px;text-align: center;}

    .content-container{position: relative;}
    .main-content{margin-left:200px;background: purple;height: 1000px;text-align:center;}
    .sidebar{
      position:absolute;
      top:0;left:0;
      background: green;
      height: 200px;
      width: 200px;
      text-align:center;
      /*like to add the following to stop from jumpy scrolling in webkit browsers*/
      -webkit-backface-visibility:hidden;
      backface-visibility:hidden; 
      -webkit-transform: translateZ(0);
      transform: translateZ(0);
    }
    .sidebar.sidebar-fixed{position:fixed;}
    .sidebar.sidebar-stop{position: absolute;bottom:0;top:auto;}
    </style>
  </head>
  <body>
    <header>Header</header>
    <div class="content-container">
      <div class="sidebar">Sidebar</div>
      <div class="main-content">Main Content</div>
    </div>
    <footer>Footer</footer>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
    <script>
     var contentTop = $('.content-container').offset().top;
     var sidebarHeight = $('.sidebar').height();
     var contentBottom = $('footer').offset().top - sidebarHeight;
     $(window).scroll(function(){
       var scrolltop = $(this).scrollTop();
       //starts the fixed sidebar
       if(scrolltop >= contentTop){
         $('.sidebar').addClass("sidebar-fixed");
       }else{
         $('.sidebar').removeClass("sidebar-fixed");
       }
       //stops the fixed sidebar
       if(scrolltop >= contentBottom){
         $('.sidebar').addClass("sidebar-stop");
       }else{
         $('.sidebar').removeClass("sidebar-stop");
       }
     });
    </script>
  </body>
</html>

Upvotes: 1

Hudson Taylor
Hudson Taylor

Reputation: 1162

You could try this:

$(window).scroll(function(){
    if ($(window).scrollTop() > /* number of pixels from top */){
        $("/* sticky div id or class */").css("position", "fixed");
    }
});

Upvotes: 1

Related Questions