177

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:

<a href="#anchor">Click me!</a>

<p id="anchor">I should be 100px below where I currently am!</p>
damon
  • 2,687
  • 8
  • 25
  • 35
  • Duplicate? http://stackoverflow.com/questions/11386807/adding-an-automatic-offset-to-the-scroll-position-for-all-hash-links-calls – XCS Jul 08 '13 at 19:49
  • Related: https://stackoverflow.com/questions/4086107/html-positionfixed-page-header-and-in-page-anchors – flen Apr 09 '17 at 07:41
  • 2
    To anyone reading this circa 2022: the top two answers are only for historical interest, jump to the [today's correct answer](https://stackoverflow.com/a/60975588)—correct as of 2020. If you can, upvote it and downvote the other two so it'll become the top answer sooner and you won't have to scroll through strata from the Mesozoic to get to it. – Ahmed Fasih Dec 10 '21 at 07:37

26 Answers26

184
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.

EDIT 1:

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).

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

EDIT 2:

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() {
    offsetAnchor();
  }, 0);
});

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

JSFiddle for this example is here

Eric Olson
  • 2,827
  • 1
  • 20
  • 21
  • 1
    This only works when the user is already on the page, it doesn't for example when the user visits `example.com/#anchor` from `example.com/about/`. – erb Mar 18 '14 at 13:58
  • 7
    Thanks @erb. The OP's question did not require that case, but to help others I added another version of the implementation. – Eric Olson Mar 18 '14 at 23:06
  • 2
    Still missing a minor detail. If you click on an anchor, then scroll up then click the same anchor again, there is no hashchange so it won't use the offset. Ideas? – Teo Maragakis Jun 04 '15 at 09:55
  • You could go for `$('a[href^="#"]').on('click', function() { offsetAnchor(); });`. This way, if the `href` of an `a` element starts with a `#`, you call the same function. – Mave Jun 10 '15 at 11:15
  • Thanks @EricOlson for this! This solution works for me in everything but IE. It even works in Edge. Any idea on a solution for IE 10 and below? – Ken Edwards Mar 10 '16 at 18:17
  • 2
    No need to jQuery - just replace `$(window).on("hashchange",` with `window.addEventListener("hashchange",` – Neon Jul 21 '16 at 10:32
  • You could update it to @Neon approach - without jQuery. – Arnis Juraga Sep 14 '16 at 10:22
  • Thanks @Neon! It is definitely worth assuming no jQuery by default. Updated as per your suggestion. – Eric Olson Sep 16 '16 at 16:40
  • @TeoMaragakis is right. Try to click the link two times. The latter click wont fire up event. – Tomasz Mularczyk Nov 22 '16 at 18:36
  • @TeoMaragakis and @Tomasz are both right, in that there's no hash "change." My fix was to listen for anchor clicks instead like so: ` $(function() { $('a[href^="#"]').on('click', function(e){ e.preventDefault(); offsetAnchor($( $.attr(this, 'href') ).offset().top); }); }); ` – Raynor Kuang Jan 05 '17 at 03:55
  • This is really nice solution and I like how it checks for a hash without adding any css to the anchor itself. – JacobLett Feb 17 '17 at 20:54
  • If you are already targeting specific id and you press link targeting it, it won't work. –  Mar 07 '17 at 18:06
  • I have added a working version of @Mave's suggestion to handle clicking the same link 2+ times in a row. See "Edit 2". – Eric Olson Mar 08 '17 at 05:51
  • I used your code (thanks for sharing) and modify it like this to scroll to a specific # `function offsetAnchor(e) { if (location.hash.length !== 0 && location.hash.length !== 7) { window.scrollTo(0, $(e.target.hash).position().top - 150); } } $(document).on('click', 'a[href^="#"]', function (e) { window.setTimeout(function () { offsetAnchor(e); }, 10); });` – Carlos A. Ortiz Mar 16 '18 at 05:07
  • @EricOlson just wondering if you could consider updating your code to give some control over the number of pixels dependent on viewport width? eg. I want 150 pixels on laptop/desktop, but on narrower screens, like mobile, I want maybe just 50. Maybe quite a few people using your code will not have taken into consideration the spacing on mobile (just a feeling!). eg. a sticky header that's fixed on mobile. – Metzed Sep 24 '19 at 14:20
  • I added event.preventDefault(); to cancel the default action (navigation) of the click. My clicked anchors point to the same page. This makes the onclick event smoother. Great answer though - helped me tremedously – Ronald Mar 02 '20 at 15:55
146

Here's the 2020 answer for this:

#anchor {
  scroll-margin-top: 100px;
}

Because it's widely supported!

user127091
  • 2,071
  • 2
  • 9
  • 16
  • 20
    Slightly less than 90% of all browsers (incl. iOS with scroll-snap-margin-top) should be enough to opt out of a javascript solution, especially if the user impact is just having to scroll. But hey, let's downvote this approach before it harms someone. – user127091 Jun 25 '20 at 13:23
  • 3
    Such a simple and working answer. Will reach 100% of support (for modern browsers) soon enough. – Leonel Becerra Jun 25 '20 at 19:18
  • 1
    also see https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-margin-top – Combobulated Jan 30 '21 at 21:39
  • 2
    I would advise [`scroll-padding`](https://caniuse.com/?search=scroll-padding) instead of [`scroll-margin`](https://caniuse.com/?search=scroll-margin) since Safari uses non-standard name `scroll-snap-margin` according to caniuse.com – ndemasie Apr 19 '21 at 16:44
  • 1
    It appears to be widely supported today. – CubicInfinity Oct 04 '21 at 19:24
  • 1
    @ndemasie The padding version doesn't seem to work with anchor links, at least on Firefox. It says the element is not scrollable. Even after adding an overflow option it still doesn't work. The margin version works fine. I would just use it by adding the non-standard name for iOS before that. – ADTC Jan 16 '23 at 13:55
111

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.

user3364768
  • 1,135
  • 1
  • 7
  • 2
74

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!
</p>

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.

renno
  • 2,659
  • 2
  • 27
  • 58
Thomas
  • 748
  • 5
  • 4
  • 4
    I prefer your solution because it does not use javascript. Thanks! – Rosario Russo Jun 18 '15 at 08:58
  • 1
    I don't understand this answer. Are you referncing this link to the object or the object itself? – CZorio May 27 '16 at 15:15
  • 4
    Very usefull with bootstrap fixed-top navbars – Outside_Box Oct 11 '16 at 12:00
  • 1
    @CZorio If I got it right, it is (ingeniously) creating an anchor element (could be something else, like "span" instead of "a") and positioning it relatively below, so that the anchor with `href="#anchor"` in it will point there, instead of pointing to the `

    ` element directly. But one warning: use `id` instead of `name` in HTML5, see: https://stackoverflow.com/questions/484719/html-anchors-with-name-or-id

    – flen Apr 09 '17 at 05:09
  • Works beautifully. And it's the only solution that is responsive, too! – Paul Brady Nov 10 '17 at 20:58
  • 1
    Truly a better solution :) – Bobby Axe Dec 15 '19 at 02:37
  • This is the one true answer :D – taykcrane Jun 22 '20 at 20:50
  • Used this solution to link to terms in a glossary. Works like a charm, but the solution is indeed presented a bit confusing. Considering the required use of ids and with a span element, the better solution would be like this: `Click me!

    I should be 100px below where I currently am!

    `
    – Tilman Jul 04 '21 at 17:41
17

This will work without jQuery and on page load.

(function() {
    if (document.location.hash) {
        setTimeout(function() {
            window.scrollTo(window.scrollX, window.scrollY - 100);
        }, 10);
    }
})();
M K
  • 9,138
  • 7
  • 43
  • 44
  • 1
    Works for me, and has the advantage over the css method that it applies to *all* hash locations on a page, so that you don't have to write a style with each hash included and remember to modify the style when you add another para with a new hash. It also allows one to style the target with a background colour without this extending 100px (or whatever) above as in the answer from @user3364768, although there is a way round that. – David May 09 '19 at 14:45
  • Why is it programmed with setTimeout instead of just 'window.scrollTo...'? – Grimm Sep 22 '22 at 14:55
  • 1
    @Grimm I guess because there is usually a delay until the page is fully rendered, images loaded etc. This can lead to layout shifts and therefore the scroll position would be off. Anyway, this is a very hacky solution. – M K Sep 23 '22 at 07:51
14

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>

<style>
.anchor{
  display: block;
  height: 115px; /*same height as header*/
  margin-top: -115px; /*same height as header*/
  visibility: hidden;
}
</style>
  • 10
    Why is this the best solution? Also, its a lot more helpful if you give some level of explanation / reasoning with an answer. – Phill Healey May 16 '16 at 14:59
  • As you are adding HTML to make an anchor anyways, adding a span is not much diffrent. Then by just adding a little bit CSS you manage to solve this problem without gaining any bugs; as some other solutions may do. – Sondre Feb 06 '20 at 18:48
  • A problem with this option is the anchor class element could cover elements above it, preventing mouse and touch interactions with them. I tried using z-index, but it didn't fix this issue. – CubicInfinity Oct 04 '21 at 21:31
12

This pure CSS solution works for me.

:target:before {
content:"";
display:block;
height:90px; /* fixed header height*/
margin:-90px 0 0; /* negative fixed header height */
}

i found it here -> https://www.wikitechy.com/tutorials/javascript/offsetting-an-html-anchor-to-adjust-for-fixed-header

Here is a fiddle: https://jsfiddle.net/e8o2p3az/

Tanasos
  • 3,928
  • 4
  • 33
  • 63
Joseph
  • 233
  • 2
  • 10
6

try this code, it has already a smooth animation when clicked the link.

$(document).on('click', 'a[href^="#"]', function (event) {
    event.preventDefault();

    $('html, body').animate({
        scrollTop: $($.attr(this, 'href')).offset().top - 100
    }, 500);
});
4

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>

<div id="link2">
    The second.
</div>

CSS:

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.

David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • 2
    The only problem with this is it now pushes that actual div further down the page. Ideally, the anchor link would just go down 100px less than it normally would. I'm willing to use JS or jQuery if necessary to achieve this. – damon Jul 08 '13 at 19:58
  • 3
    This doesn't solve the problem, this simply adds white space before the element. – XCS Jul 08 '13 at 20:18
  • user1925805: see the updated answer for a JavaScript solution. @Cristy: I *know*, I explicitly stated that in the answer itself: *the element is still positioned at the top of the window, but it appears, visibly, to be positioned some distance from the top*. – David Thomas Jul 08 '13 at 20:19
  • Best, clean solution with your JS. Thanks it works for me very well! – DanielaB67 Dec 17 '17 at 20:18
  • This only works hashchanges happened within the page. But use got redirected with ID, then this doesnt works – Rohan Khude Jan 02 '18 at 12:09
4

This should work:

    $(document).ready(function () {
    $('a').on('click', function (e) {
        // e.preventDefault();

        var target = this.hash,
            $target = $(target);

       $('html, body').stop().animate({
        'scrollTop': $target.offset().top-49
    }, 900, 'swing', function () {
    });

        console.log(window.location);

        return false;
    });
});

Just change the .top-49 to what fits with your anchor link.

dMehta
  • 55
  • 1
  • 3
3

If you use explicit anchor names such as,

<a name="sectionLink"></a>
<h1>Section<h1>

then in css you can simply set

A[name] {
    padding-top:100px;
}

This will work as long as your HREF anchor tags don't also specify a NAME attribute

Mespr
  • 31
  • 2
3

Eric's answer is great, but you really don't need that timeout. If you're using jQuery, you can just wait for the page to load. So I'd suggest changing the code to:

// 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).on("hashchange", function () {
    offsetAnchor();
});

// Let the page finish loading.
$(document).ready(function() {
    offsetAnchor();
});

This also gets us rid of that arbitrary factor.

rppc
  • 68
  • 4
2

I just found an easy solution for myself. Had an margin-top of 15px

HTML

<h2 id="Anchor">Anchor</h2>

CSS

h2{margin-top:-60px; padding-top:75px;}
Gero
  • 31
  • 2
1

The easiest solution:

CSS

#link {
    top:-120px; /* -(some pixels above) */
    position:relative;
    z-index:5;
}

HTML

<body>
    <a href="#link">Link</a>
    <div>
        <div id="link"></div> /*this div should placed inside a target div in the page*/
        text
        text
        text
    <div>
</body>
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
1

A variant of Thomas' solution: CSS element>element selectors can be handy here:

CSS

.paddedAnchor{
  position: relative;
}
.paddedAnchor > a{
  position: absolute;
  top: -100px;
}

HTML

<a href="#myAnchor">Click Me!</a>

<span class="paddedAnchor"><a name="myAnchor"></a></span>

A click on the link will move the scroll position to 100px above wherever the element with a class of paddedAnchor is positioned.

Supported in non-IE browsers, and in IE from version 9. For support on IE 7 and 8, a <!DOCTYPE> must be declared.

HondaGuy
  • 1,251
  • 12
  • 29
1

Using only css and having no problems with covered and unclickable content before (the point of this is the pointer-events:none):

CSS

.anchored::before {
    content: '';
    display: block;
    position: relative;
    width: 0;
    height: 100px;
    margin-top: -100px;
}

HTML

<a href="#anchor">Click me!</a>
<div style="pointer-events:none;">
<p id="anchor" class="anchored">I should be 100px below where I currently am!</p>
</div>
dantefff
  • 37
  • 3
1

Put this in style :

.hash_link_tag{margin-top: -50px; position: absolute;}

and use this class in separate div tag before the links, example:

<div class="hash_link_tag" id="link1"></div> 
<a href="#link1">Link1</a>

or use this php code for echo link tag:

function HashLinkTag($id)
{
    echo "<div id='$id' class='hash_link_tag'></div>";
}
MohsenB
  • 1,669
  • 18
  • 29
0

I know this is a bit late, but I found something very important to put in your code if you are using Bootstrap's Scrollspy. (http://getbootstrap.com/javascript/#scrollspy)

This was driving me nuts for hours.

The offset for scroll spy MUST match the window.scrollY or else you'll run the risk of:

  1. Getting a weird flicker effect when scrolling
  2. Youll find that when you click on anchors, youll land in that section, but scroll spy will assume you are a section above it.

 var body = $('body');
    body.scrollspy({
        'target': '#nav',
        'offset': 100 //this must match the window.scrollY below or you'll have a bad time mmkay
});

$(window).on("hashchange", function () {
        window.scrollTo(window.scrollX, window.scrollY - 100);
});
beefsupreme
  • 123
  • 10
0

Based on @Eric Olson solution just modify a little to include the anchor element that I want to go specifically

// Function that actually set offset
function offsetAnchor(e) {
    // location.hash.length different to 0 to ignore empty anchor (domain.me/page#)
    if (location.hash.length !== 0) {
        // Get the Y position of the element you want to go and place an offset
        window.scrollTo(0, $(e.target.hash).position().top - 150);
    }
}

// Catch the event with a time out to perform the offset function properly
$(document).on('click', 'a[href^="#"]', function (e) {
    window.setTimeout(function () {
        // Send event to get the target id later
        offsetAnchor(e);
    }, 10);
});
Carlos A. Ortiz
  • 169
  • 2
  • 6
0

I just have the same problem. I have a nav posited pixed and i want the angkor to start under the nav. The solution of window.addEventListener... not work for me because i set my page to be scroll-behavior:smooth so it set the offset instead scroll to the angkor. the setTimeout() work if the time is anough for scroll to the end but it still not looking good. so my solution was to add a posited absolute div in the angkor, with height:[the height of the nav] and bottom:100%. in this case this div ended in the top of the angkor element, and start at the position where you what the angkor to scroll to. now all what i do is set the angkor link to this absolute div and the wor done :)

html,body{
    margin:0;
    padding:0;
    scroll-behavior:smooth;
}

nav {
    height:30px;
    width:100%;
    font-size:20pt;
    text-align:center;
    color:white;
    background-color:black;
    position:relative;
}

#my_nav{
    position:fixed;
    z-index:3;
}
#fixer_nav{
    position:static;
}

#angkor{
    position:absolute;
    bottom:100%;
    height:30px;
}
<nav id="my_nav"><a href="#angkor">fixed position nav<a/></nav>
<nav id="fixer_nav"></nav>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nec lacus vel eros rutrum volutpat. Cras ultrices enim sit amet odio dictum, eget consectetur mi pellentesque. Sed mollis gravida nulla, eu euismod turpis efficitur id. Integer pretium posuere fringilla. Aenean laoreet, augue non pharetra elementum, lectus massa congue orci, a imperdiet neque enim ut dui. Praesent commodo orci bibendum leo suscipit viverra. Nunc fermentum semper eleifend. Pellentesque suscipit nulla aliquet, egestas lectus sed, egestas dui. Vivamus scelerisque maximus nibh, ac dignissim nunc tempor a. Praesent facilisis non lacus et aliquam. Proin ultricies lacus vitae nibh ullamcorper gravida. Proin elit arcu, convallis eget posuere quis, placerat id augue. Fusce ex risus, tempus nec orci vitae, feugiat faucibus quam. Integer risus metus, ornare et rhoncus vitae, accumsan a urna.
</p>

<nav><div id="angkor"></div>The angkor</nav>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nec lacus vel eros rutrum volutpat. Cras ultrices enim sit amet odio dictum, eget consectetur mi pellentesque. Sed mollis gravida nulla, eu euismod turpis efficitur id. Integer pretium posuere fringilla. Aenean laoreet, augue non pharetra elementum, lectus massa congue orci, a imperdiet neque enim ut dui. Praesent commodo orci bibendum leo suscipit viverra. Nunc fermentum semper eleifend. Pellentesque suscipit nulla aliquet, egestas lectus sed, egestas dui. Vivamus scelerisque maximus nibh, ac dignissim nunc tempor a. Praesent facilisis non lacus et aliquam. Proin ultricies lacus vitae nibh ullamcorper gravida. Proin elit arcu, convallis eget posuere quis, placerat id augue. Fusce ex risus, tempus nec orci vitae, feugiat faucibus quam. Integer risus metus, ornare et rhoncus vitae, accumsan a urna.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nec lacus vel eros rutrum volutpat. Cras ultrices enim sit amet odio dictum, eget consectetur mi pellentesque. Sed mollis gravida nulla, eu euismod turpis efficitur id. Integer pretium posuere fringilla. Aenean laoreet, augue non pharetra elementum, lectus massa congue orci, a imperdiet neque enim ut dui. Praesent commodo orci bibendum leo suscipit viverra. Nunc fermentum semper eleifend. Pellentesque suscipit nulla aliquet, egestas lectus sed, egestas dui. Vivamus scelerisque maximus nibh, ac dignissim nunc tempor a. Praesent facilisis non lacus et aliquam. Proin ultricies lacus vitae nibh ullamcorper gravida. Proin elit arcu, convallis eget posuere quis, placerat id augue. Fusce ex risus, tempus nec orci vitae, feugiat faucibus quam. Integer risus metus, ornare et rhoncus vitae, accumsan a urna.

</p>
Yosef Tukachinsky
  • 5,570
  • 1
  • 13
  • 29
0

i was facing the similar issue and i resolved by using following code

$(document).on('click', 'a.page-scroll', function(event) {
        var $anchor = $(this);
        var desiredHeight = $(window).height() - 577;
        $('html, body').stop().animate({
            scrollTop: $($anchor.attr('href')).offset().top - desiredHeight
        }, 1500, 'easeInOutExpo');
        event.preventDefault();
    });
Umair Mehmood
  • 514
  • 1
  • 11
  • 24
0

I had this same issue, and there's a really quick and simple solution without CSS of JS. Just create a separate unstyled div with an ID like "aboutMeAnchor and just place it well above the section you actually want to land on.

Artem
  • 7
  • 3
0

This is also a good solution. Make a div above the destination div like this and link the a to this div;

<div class="destination" id="link"></div> /**Needs to be above the destination**/

.destination {
    position:absolute;
    z-index:-1;
    left:0;
    margin-top:-100px;/* height of nav*/
}
İsmail Y.
  • 3,579
  • 5
  • 21
  • 29
Walkman
  • 41
  • 2
0

I was trying to do something similar and what finally worked for me is to add the pseudo element ::before to the div you want to scroll to. This will add a blank space before the element and the anchor link will scroll to the top of this blank space. For example:

#anchor::before {
  content: "";
  display: block;
  height: 60px;
}
vgm
  • 31
  • 1
0

I found a surprising solution to what I think is basically the same issue about the scroll-position of the target of anchor-links.

I have a page which displays a long document with sub-sections whose headers I mark by putting a bookmark dom-element right above them like this:

<div class = "TB_BookMark"
        id = "someId"  
></div>
<h3 class="TB">Section 1</h3>

The idea is that user can navigate into the document's sub-sections by clicking on links in a side-pane. The first such link should scroll the window to the start of the page. Note that the content of the bookmark-div above is empty meaning it should take no space from the page, and thus navigating to the first link should navigate to the beginning of the page.

The problem was that clicking the first link scrolled the page so that the first section-header was immediately at the top of visible area with no whitespace above it. In other words the page was scrolled down a little from the top. Whereas when the page was loaded or reloaded there is (and should be) a visible white-space margin above the first section-header.

I believe this is the same issue that the original question describes. It seemed there was no way to get the first link to scroll to the very beginning of the page.

Problem is that what you see when you load the page is different from what you see when you click the first link. It doesn't look good when there is no longer a whitespace-margin above the first header, or alternately there would be too big a margin when you load or reload the page.

The way I got it to work is this CSS:

.TB_Bookmark
{ border:solid 0px    Transparent;  /* Does NOT do what I want. */
  border:solid 0.01px Transparent;  /* Does what I want. */
}

h3.TB
{ margin-top:12px;
  margin-bottom:12px;
}

body
{ margin-top: 0px;
}

All of the above was needed to get it to work except the first border-definition which I left as an example of what does NOT work. The 2nd border-definition of course overrides the first and thus takes effect.

Why "border:solid 0.01px;" works but "border:solid 0px;" does not I don't understand. There should not be a big difference between 0 an 0.01 should there? This solution works both on Chrome and Firefox and stops working on both if I use "border:solid 0px;".

Panu Logic
  • 2,193
  • 1
  • 17
  • 21
-2
<a href="#anchor">Click me!</a>

<div style="margin-top: -100px; padding-top: 100px;" id="anchor"></div>
<p>I should be 100px below where I currently am!</p>
  • 4
    That's essentially the same answer as [this one](http://stackoverflow.com/a/22095246). If you post answers to old question, try to add something new. For example, you could describe why that works. – Artjom B. Jun 10 '15 at 11:21
  • 1
    I'd argue that any answer should have some sort of description as to why it works. ;-) – Phill Healey May 16 '16 at 15:00