how can I make a div stick to the top of the screen once it's been scrolled to?-Collection of common programming errors
?egDwightI 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
CMSYou 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.
ThiefMasterYou’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 WAnd 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 RussoMy 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)); }); };
AdamS 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
ForgeThe 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).
infinityYou 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'}); }
ArtistanI 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)'); } });
newdarkI 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.
VSHIn javascript you can do:
var element = document.getElementById("myid"); element.style.position = "fixed"; element.style.top = "0%";
DanHere’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.
kundeHere 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 withposition:absolute
CSS property.