Hi all,

I have a menu on the left side of my design. When the user scrolls and the object hits the top of the screen I want it to float there. I have the float working fine now, but how can I say "Only float when you meet the top of the display?"

This is the CSS for the object:

.well {
  min-height: 20px;
  padding: 19px;
  margin-bottom: 20px;
  background-color: #f5f5f5;
  border: 1px solid #e3e3e3;
  -webkit-border-radius: 4px;
     -moz-border-radius: 4px;
          border-radius: 4px;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
            position:fixed !important;
            position: absolute; /*ie6 */
}

Thanks in advance,
Michael

Dani AI

Generated

Short answer: use CSS position: sticky where possible, and fall back to a tiny scroll script if you need to support older browsers or want extra control. was right that toggling positioning on scroll works; below are a modern, low-friction option plus a compact vanilla-JS fallback that avoids the layout jump that comes from switching an element to fixed.

/* modern, simplest solution */
.sidebar {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 100;
}
/* fallback class used by the script */
.sidebar.fixed {
  position: fixed;
  top: 0;
  z-index: 100;
  /* keep width stable; JS will set an explicit width when fixing */
}
// vanilla fallback: measure once, insert a placeholder to avoid jump
(function(){
  var el = document.querySelector('.sidebar');
  if (!el) return;
  var placeholder = document.createElement('div');
  var origTop = el.getBoundingClientRect().top + window.pageYOffset;
  var isFixed = false;

  function updatePlaceholder(){
    placeholder.style.width = el.offsetWidth + 'px';
    placeholder.style.height = el.offsetHeight + 'px';
  }

  function onScroll(){
    var y = window.pageYOffset || document.documentElement.scrollTop;
    if (y >= origTop && !isFixed){
      updatePlaceholder();
      el.parentNode.insertBefore(placeholder, el);
      el.classList.add('fixed');
      el.style.width = placeholder.style.width;
      isFixed = true;
    } else if (y < origTop && isFixed){
      el.classList.remove('fixed');
      if (placeholder.parentNode) placeholder.parentNode.removeChild(placeholder);
      el.style.width = '';
      isFixed = false;
    }
  }

  window.addEventListener('scroll', function(){ requestAnimationFrame(onScroll); });
  window.addEventListener('resize', function(){ origTop = el.getBoundingClientRect().top + window.pageYOffset; if (isFixed) updatePlaceholder(); });
})();

Troubleshooting notes: set a fixed width when fixed (or let the script copy it), watch z-index so the menu sits above content, and avoid fixing if the sidebar is taller than the viewport (or add logic to pin/unpin at the container bottom). For most modern sites the sticky CSS is simplest and smoother; use the script only for older-browser support or special cases. This ties back to ’s original layout needs and ’s suggestion to toggle positioning on scroll.

Recommended Answers

All 4 Replies

Hmm, you'd need JavaScript for this to work. Do you know JS?
I don't have time to write the code right now and test, but here's probably how I'd do it:

  1. Originally set .well's position to relative
  2. Get the original y-coordinate of the top of the menu
  3. If the y-coordinate of the top of the browser viewport is >= to #2 above, change the positioning of .well to fixed.
  4. If the y-coordinate then becomes < #2, toggle back to relative

This may prove useful for finding offsets:
http://stackoverflow.com/questions/1567327/using-jquery-to-get-elements-position-relative-to-viewport

commented: very helpful +1

Thats perfect, thanks! :D

Glad to help! Love the sig btw ;)

It's too true to deny xD

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.