how can I make a div stick to the top of the screen once it's been scrolled to?-Collection of common programming errors


  • ?egDwight

    I would like to create a div, that is situated beneath a block of content but that once the page has been scrolled enough to contact its top boundary, becomes fixed in place and scrolls with the page. I know I’ve seen at least one example of this online but I cannot remember it for the life of me.

    Any thoughts?

  • 15 Answers


  • CMS

    You could use simply css, positioning your element as fixed:

    .fixedElement {
        background-color: #c0c0c0;
        position:fixed;
        top:0;
        width:100%;
        z-index:100;
    }
    

    Edit: You should have the element with position absolute, once the scroll offset has reached the element, it should be changed to fixed, and the top position should be set to zero.

    You can detect the top scroll offset of the document with the scrollTop function:

    $(window).scroll(function(e){ 
      $el = $('.fixedElement'); 
      if ($(this).scrollTop() > 200 && $el.css('position') != 'fixed'){ 
        $('.fixedElement').css({'position': 'fixed', 'top': '0px'}); 
      } 
    });
    

    When the scroll offset reached 200, the element will stick to the top of the browser window, because is placed as fixed.

    Check this new example.


  • ThiefMaster

    You’ve seen this example on Google Code’s issue page and (only recently) on Stack Overflow’s edit page.

    CMS’s answer doesn’t revert the positioning when you scroll back up. Here’s the shamelessly stolen code from Stack Overflow:

    function moveScroller() {
        var move = function() {
            var st = $(window).scrollTop();
            var ot = $("#scroller-anchor").offset().top;
            var s = $("#scroller");
            if(st > ot) {
                s.css({
                    position: "fixed",
                    top: "0px"
                });
            } else {
                if(st  div_top) {
                // Make the div sticky.
                $mainMenuBar.addClass('stick');
                $mainMenuBarAnchor.height($mainMenuBar.height());
            }
            else {
                // Unstick the div.
                $mainMenuBar.removeClass('stick');
                $mainMenuBarAnchor.height(0);
            }
        });
    });
    

  • Jim W

    And here’s how without jquery

        
    
        
        
        
        #productMenuBar {
        border:1px solid #00ffff;
    
        text-align:center;
    
        z-index:9999;
        width:100%;
        max-width: 850px;
        margin: 0 auto; left:0px; right:0px;
    
    
        }
        
    
        
        var startProductBarPos=-1;
        window.onscroll=function(){
            var bar = document.getElementById('productMenuBar');
            if(startProductBarPosstartProductBarPos){
                bar.style.position='fixed';
                bar.style.top=0;
            }else{
                bar.style.position='relative';
            }
    
        };
    
    
        function findPosY(obj) {
            var curtop = 0;
            if (typeof (obj.offsetParent) != 'undefined' && obj.offsetParent) {
                while (obj.offsetParent) {
                    curtop += obj.offsetTop;
                    obj = obj.offsetParent;
                }
                curtop += obj.offsetTop;
            }
            else if (obj.y)
                curtop += obj.y;
            return curtop;
        }
        
        
        
        and this
    is
    above
    LOGO hello



































    world

































































































































  • Josh Russo

    My solution is a little verbose, but it handles variable positioning from the left edge for centered layouts.

    // Ensurs that a element (usually a div) stays on the screen
    //   aElementToStick   = The jQuery selector for the element to keep visible
    global.makeSticky = function (aElementToStick) {
        var $elementToStick = $(aElementToStick);
        var top = $elementToStick.offset().top;
        var origPosition = $elementToStick.css('position');
    
        function positionFloater(a$Win) {
            // Set the original position to allow the browser to adjust the horizontal position
            $elementToStick.css('position', origPosition);
    
            // Test how far down the page is scrolled
            var scrollTop = a$Win.scrollTop();
            // If the page is scrolled passed the top of the element make it stick to the top of the screen
            if (top < scrollTop) {
                // Get the horizontal position
                var left = $elementToStick.offset().left;
                // Set the positioning as fixed to hold it's position
                $elementToStick.css('position', 'fixed');
                // Reuse the horizontal positioning
                $elementToStick.css('left', left);
                // Hold the element at the top of the screen
                $elementToStick.css('top', 0);
            }
        }
    
        // Perform initial positioning
        positionFloater($(window));
    
        // Reposition when the window resizes
        $(window).resize(function (e) {
            positionFloater($(this));
        });
    
        // Reposition when the window scrolls
        $(window).scroll(function (e) {
            positionFloater($(this));
        });
    };
    

  • Adam

    S T O P !!! YOU WILL NOT WANT TO MISS THIS PIECE OF WORK!

    I post this CSS ONLY Top of screen scroll bar. Solved all the problem with ONLY CSS, NO JavaScript, NO JQuery, No Brain work (lol).

    Enjoy my fiddle 😀 all the codes are included in there 🙂

    CSS

    #menu {
    position: fixed;
    height: 60px;
    width: 100%;
    top: 0;
    left: 0;
    border-top: 5px solid #a1cb2f;
    background: #fff;
    -moz-box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
    -webkit-box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
    box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
    z-index: 999999;
    }
    
    .w {
        width: 900px;
        margin: 0 auto;
        margin-bottom: 40px;
    }

    HTML

    
    

    The Menu

    Put the content long enough so you can see the effect here 🙂

    Oh, and the reference is in there as well, for the fact he deserve his credit

    CSS ONLY Top of screen scroll bar


  • Amber

  • Forge

    The accepted answer works but doesn’t move back to previous position if you scroll above it. It is always stuck to the top after being placed there.

      $(window).scroll(function(e) {
        $el = $('.fixedElement');
        if ($(this).scrollTop() > 42 && $el.css('position') != 'fixed') {
          $('.fixedElement').css( 'position': 'fixed', 'top': '0px');
    
        } else if ($(this).scrollTop() < 42 && $el.css('position') != 'relative') {
          $('.fixedElement').css( 'relative': 'fixed', 'top': '42px');
    //this was just my previous position/formating
        }
      });
    

    jleedev’s response whould work, but I wasn’t able to get it to work. His example page also didn’t work (for me).


  • infinity

    You can add 3 extra rows so when the user scroll back to the top, the div will stick on its old place:

    Here is the code:

    if ($(this).scrollTop() < 200 && $el.css('position') == 'fixed'){
        $('.fixedElement').css({'position': 'relative', 'top': '200px'});
    }
    

  • Artistan

    I have links setup in a div so it is a vertical list of letter and number links.

    #links {
        float:left;
        font-size:9pt;
        margin-left:0.5em;
        margin-right:1em;
        position:fixed;
        text-align:center;
        width:0.8em;
    }
    

    I then setup this handy jQuery function to save the loaded position and then change the position to fixed when scrolling beyond that position.

    NOTE: this only works if the links are visible on page load!!

    var listposition=false;
    jQuery(function(){
         try{
            ///// stick the list links to top of page when scrolling
            listposition = jQuery('#links').css({'position': 'static', 'top': '0px'}).position();
            console.log(listposition);
            $(window).scroll(function(e){
                $top = $(this).scrollTop();
                $el = jQuery('#links');
                //if(typeof(console)!='undefined'){
                //    console.log(listposition.top,$top);
                //}
                if ($top > listposition.top && $el.css('position') != 'fixed'){
                    $el.css({'position': 'fixed', 'top': '0px'});
                }
                else if ($top < listposition.top && $el.css('position') == 'fixed'){
                    $el.css({'position': 'static'});
                }
            });
    
        } catch(e) {
            alert('Please vendor [email protected] (Myvendor JavaScript Issue)');
        }
    });
    

  • newdark

    I used some of the work above to create this tech. I improved it a bit and thought I would share my work. Hope this helps.

    jsfuddle Code

    function scrollErrorMessageToTop() {
        var flash_error = jQuery('#flash_error');
        var flash_position = flash_error.position();
    
        function lockErrorMessageToTop() {
            var place_holder = jQuery("#place_holder");
            if (jQuery(this).scrollTop() > flash_position.top && flash_error.attr("position") != "fixed") {
                flash_error.css({
                    'position': 'fixed',
                    'top': "0px",
                    "width": flash_error.width(),
                    "z-index": "1"
                });
                place_holder.css("display", "");
            } else {
                flash_error.css('position', '');
                place_holder.css("display", "none");
            }
    
        }
        if (flash_error.length > 0) {
            lockErrorMessageToTop();
    
            jQuery("#flash_error").after(jQuery(""));
            var place_holder = jQuery("#place_holder");
            place_holder.css({
                "height": flash_error.height(),
                "display": "none"
            });
            jQuery(window).scroll(function(e) {
                lockErrorMessageToTop();
            });
        }
    }
    scrollErrorMessageToTop();?
    

    This is a little bit more dynamic of a way to do the scroll. It does need some work and I will at some point turn this into a pluging but but this is what I came up with after hour of work.


  • VSH

    In javascript you can do:

    var element = document.getElementById("myid");
    element.style.position = "fixed";
    element.style.top = "0%";
    

  • Dan

    Here’s one more version to try for those having issues with the others. It pulls together the techniques discussed in this duplicate question, and generates the required helper DIVs dynamically so no extra HTML is required.

    CSS:

    .sticky { position:fixed; top:0; }
    

    JQuery:

    function make_sticky(id) {
        var e = $(id);
        var w = $(window);
        $('').insertBefore(id);
        $('').hide().css('height',e.outerHeight()).insertAfter(id);
        var n = e.next();
        var p = e.prev();
        function sticky_relocate() {
          var window_top = w.scrollTop();
          var div_top = p.offset().top;
          if (window_top > div_top) {
            e.addClass('sticky');
            n.show();
          } else {
            e.removeClass('sticky');
            n.hide();
          }
        }
        w.scroll(sticky_relocate);
        sticky_relocate();
    }
    

    To make an element sticky, do:

    make_sticky('#sticky-elem-id');
    

    When the element becomes sticky, the code manages the position of the remaining content to keep it from jumping into the gap left by the sticky element. It also returns the sticky element to its original non-sticky position when scrolling back above it.


  • kunde

    Here is another option:

    JAVASCRIPT

    var initTopPosition= $('#myElementToStick').offset().top;   
    $(window).scroll(function(){
        if($(window).scrollTop() > initTopPosition)
            $('#myElementToStick').css({'position':'fixed','top':'0px'});
        else
            $('#myElementToStick').css({'position':'absolute','top':initTopPosition+'px'});
    });
    

    Your #myElementToStick should start with position:absolute CSS property.