Fixed page header overlaps in-page anchors
Solution 1:
If you can’t or don’t want to set a new class, add a fixed-height ::before
pseudo-element to the :target
pseudo-class in CSS:
:target::before {
content: "";
display: block;
height: 60px; /* fixed header height*/
margin: -60px 0 0; /* negative fixed header height */
}
Or scroll the page relative to :target
with jQuery:
var offset = $(':target').offset();
var scrollto = offset.top - 60; // minus fixed header height
$('html, body').animate({scrollTop:scrollto}, 0);
Solution 2:
I had the same problem. I solved it by adding a class to the anchor element with the topbar height as the padding-top value.
<h1><a class="anchor" name="barlink">Bar</a></h1>
I used this CSS:
.anchor { padding-top: 90px; }
Solution 3:
html {
scroll-padding-top: 70px; /* height of sticky header */
}
from: https://css-tricks.com/fixed-headers-on-page-links-and-overlapping-content-oh-my/
Solution 4:
I use this approach:
/* add class="jumptarget" to all targets. */
.jumptarget::before {
content:"";
display:block;
height:50px; /* fixed header height*/
margin:-50px 0 0; /* negative fixed header height */
}
It adds an invisible element before each target. It works IE8+.
Here are more solutions: http://nicolasgallagher.com/jump-links-and-viewport-positioning/
Solution 5:
From 4/2021 there is single non-hacky and fully cross-browser solution:
h1 {
scroll-margin-top: 50px
}
It is part of CSS Scroll Snap spec. Runs on all modern browsers.