Div anchors scrolling too far

Viewed 70811

I'm using a static bar at the top of my site, about 20px high. When I click an anchor link(for those who don't know, the navigation on wikipedia works like that. Click a title and the browser goes down to it) part of the text disappears behind that top bar.

Is there any way to stop this from happening? I'm not in a position where I can use an iFrame. Onlything I can think of is make it scroll back a bit each time, but is there another way? Some CSS setting to manipulate the body or something?

7 Answers

You could just use CSS without any javascript.

Give your anchor a class:

<a class="anchor"></a>

You can then position the anchor an offset higher or lower than where it actually appears on the page, by making it a block element and relatively positioning it. -250px will position the anchor up 250px

a.anchor{display: block; position: relative; top: -250px; visibility: hidden;}

By Jan see offsetting an html anchor to adjust for fixed header

Here's a modern, one-line, pure CSS solution:

scroll-margin-top: 20px;

It does exactly what it sounds like: acts as if there is a margin, but only when in the context of scrolling. So scroll-margin-top: 20px; on an element means that clicking an anchor tag for that element will scroll the page to 20px above the element.

Compatibility (See caniuse)

No support for IE. Also, Safari versions 11-14 use a non-standard name: scroll-snap-margin-top (but otherwise works as expected). Safari 14.1+ works with the standard name.

Full example:

nav{
  position: fixed;
  top:0;
  left:0;
  background: black;
  color: white;
  width: 100%;
}

#after-nav{
  margin-top: 25px;
}

#section-1{
  width: 100%;
  background: green;
  height: 500px;
  scroll-margin-top: 20px;
}

#section-2{
  width: 100%;
  background: blue;
  height: 500px;
  scroll-margin-top: 20px;
}

ul{
margin-top: 0;
}
<nav>
Nav bar: 20px (as in OP)
</nav>
<div id="after-nav">
Table of contents:
<ul>
<li><a href="#section-1">Section 1</a></li>
<li><a href="#section-2">Section 2</a></li>
</ul>


<div id="section-1">Section 1</div>
<div id="section-2">Section 2</div>
</div>

I had the same problem. Here's a jQuery solution

$('a[href^="#"]').on('click',function (e) {
    e.preventDefault();
    var target = this.hash;
    var $trget = $(target);
    // Example: your header is 70px tall.
    var newTop = $trget.offset().top - 70; 
    $('html, body').animate ({
        scrollTop: newTop
    }, 500, 'swing', function () {
        window.location.hash = target;
    }); 
});

After searching through all of the other answers above, the one that worked for me to fix my scrolling anchor issue was the following:

Code:

#idname {
    scroll-margin-top: 20px;
}

Thank you to those above who suggested this answer. You can obviously change the pixel number for the margin. I changed it from 20px to 40px and it works like a charm.

Related