Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding an automatic offset to the scroll position for all hash-links/calls

I have the following problem:

Like on Facebook, I have a menu bar at the top of the page that is always visible (position: fixed;). When I now click hash-links on my page (or load a new page with a hash in the url) to jump to a certain element on the page, the browser always scrolls this element to the very top of the page, meaning that the element is behind the top menu bar, afterwards.

I'd like to add some Javascript (jQuery or normal Javascript) that automatically adds a (negative) offset to this scroll position, so that the linked element is positioned right under the top menu bar when a link is clicked or the page is loaded. But I don't just want to add event listeners to all links that take care of this. I also want a solution that works, if the page is loaded with a hash portion in the url using the browser's address bar (or when linking to a different page with a hash at the end of the url).

Can you help me with this, please? Thanks in advance! :)

like image 719
René Schubert Avatar asked Jul 08 '12 21:07

René Schubert


Video Answer


3 Answers

I actually found a solution myself that worked for me, using only css:

I added a margin-top: -40px; and padding-top: 40px; to the element that the jump-link was pointing to. This works for all major browsers: IE (7-9), Firefox, Opera, Chrome and Safari.

Only problem: In case that this element is after a floated element, the negative margin doesn't work (meaning the positive padding becomes visible). Please comment, if anyone knows a solution/workaround for this. I'll update my post then. Thank you!

like image 132
René Schubert Avatar answered Oct 12 '22 03:10

René Schubert


Nowadays in 2021 there's a nice simple only-css solution with :target and scroll-margin-top

:target {
    scroll-margin-top: 100px;
}

It works in all major browsers

References:

  • https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-margin-top
  • https://developer.mozilla.org/en-US/docs/Web/CSS/%3Atarget
like image 10
migli Avatar answered Oct 12 '22 04:10

migli


I found this way of adding a :before in the css seems to work well.

h2:before { 
  display: block; 
  content: " "; 
  margin-top: -285px; 
  height: 285px; 
  visibility: hidden; 
}

More at CSS Tricks website

like image 8
phocks Avatar answered Oct 12 '22 04:10

phocks