Make anchor link go some pixels above where it’s linked to

Make anchor link go some pixels above where it’s linked to

I’m not sure the best way to ask/search for this question:
When you click on an anchor link, it brings you to that section of the page with the linked-to area now at the VERY TOP of the page. I would like the anchor link to send me to that part of the page, but I would like some space at the top. As in, I don’t want it to send me to the linked-to part with it at the VERY TOP, I would like 100 or so pixels of space there.
Does this make sense? Is this possible?
Edited to show code – it’s just an anchor tag:
Click me!

I should be 100px below where I currently am!


Solution 1:

window.addEventListener("hashchange", function () {
    window.scrollTo(window.scrollX, window.scrollY - 100);

This will allow the browser to do the work of jumping to the anchor for us and then we will use that position to offset from.


As was pointed out by @erb, this only works if you are on the page while the hash is changed. Entering the page with a #something already in the URL does not work with the above code. Here is another version to handle that:

// The function actually applying the offset
function offsetAnchor() {
    if(location.hash.length !== 0) {
        window.scrollTo(window.scrollX, window.scrollY - 100);

// This will capture hash changes while on the page
window.addEventListener("hashchange", offsetAnchor);

// This is here so that when you enter the page with a hash,
// it can provide the offset in that case too. Having a timeout
// seems necessary to allow the browser to jump to the anchor first.
window.setTimeout(offsetAnchor, 1); // The delay of 1 is arbitrary and may not always work right (although it did in my testing).

To use jQuery, you could just replace window.addEventListener with $(window).on in the examples. Thanks @Neon.


As pointed out by a few, the above will fail if you click on the same anchor link two or more times in a row because there is no hashchange event to force the offset.

This solution is very slightly modified version of the suggestion from @Mave and uses jQuery selectors for simplicity

// The function actually applying the offset
function offsetAnchor() {
  if (location.hash.length !== 0) {
    window.scrollTo(window.scrollX, window.scrollY - 100);

// Captures click events of all <a> elements with href starting with #
$(document).on('click', 'a[href^="#"]', function(event) {
  // Click events are captured before hashchanges. Timeout
  // causes offsetAnchor to be called after the page jump.
  window.setTimeout(function() {
  }, 0);

// Set the offset when entering page with hash present in the url
window.setTimeout(offsetAnchor, 0);

JSFiddle for this example is here

Solution 2:

Working only with css you can add a padding to the anchored element (as in a solution above)
To avoid unnecessary whitespace you can add a negative margin of the same height:

#anchor {
    padding-top: 50px;
    margin-top: -50px;

I am not sure if this is the best solution in any case, but it works fine for me.

Solution 3:

Even better solution:

<p style="position:relative;">
    <a name="anchor" style="position:absolute; top:-100px;"></a>
    I should be 100px below where I currently am!

Just position the <a> tag with absolute positioning inside of a relatively positioned object.

Works when entering the page or through a hash change within page.

Solution 4:

Best Solution

<span class="anchor" id="section1"></span>
<div class="section"></div>

<span class="anchor" id="section2"></span>
<div class="section"></div>

<span class="anchor" id="section3"></span>
<div class="section"></div>

  display: block;
  height: 115px; /*same height as header*/
  margin-top: -115px; /*same height as header*/
  visibility: hidden;

Solution 5:

This will work without jQuery and on page load.

(function() {
    if (document.location.hash) {
        setTimeout(function() {
            window.scrollTo(window.scrollX, window.scrollY - 100);
        }, 10);

Solution 6:

To link to an element, and then ‘position’ that element an arbitrary distance from the top of the page, using pure CSS, you’d have to use padding-top, that way the element is still positioned at the top of the window, but it appears, visibly, to be positioned some distance from the top of the view-port, for example:

<a href="#link1">Link one</a>
<a href="#link2">Link two</a>

<div id="link1">
    The first.

<div id="link2">
    The second.


div {
    /* just to force height, and window-scrolling to get to the elements.
       Irrelevant to the demo, really */
    margin-top: 1000px;
    height: 1000px;

#link2 {
    /* places the contents of the element 100px from the top of the view-port */
    padding-top: 100px;

JS Fiddle demo.

To use a plain JavaScript approach:

function addMargin() {
    window.scrollTo(0, window.pageYOffset - 100);

window.addEventListener('hashchange', addMargin);

JS Fiddle demo.