I ran into an issue recently where I wanted to use anchors to jump to different sections within a long web page. The problem was every time I clicked the page would jump, but a fixed header would cover part of each section’s content. After a bit of searching, some trial and error, a simple HTML adjustment and a bit of CSS and the problem was solved.

The Setup and the Problem

I started with a header that was set up like so: (styles inlined for clarification)
<div class="header" style="position: fixed; top: 0;"></div>
Near the top of the page was an unordered list that contains the anchor links:
<ul>
  <li><a href="#section1">Anchor Text</a></li>
  <li><a href="#section2">Anchor Text</a></li>
  <li><a href="#section3">Anchor Text</a></li>
</ul>
And of course there was each section of content which I wanted to jump to:
<div class="section" id="section1"></div>
<div class="section" id="section2"></div>
<div class="section" id="section3"></div>
Now as you can see, I started with adding the IDs to each section. This is when I noticed that clicking on one of the anchor links would actually cause the page to jump to the right section, but some of the content in the section would get covered by the header which is fixed and stays at the top of the page when scrolling occurs. To overcome the issue a minor HTML adjustment was made and a small amount of CSS was also added to bring it all together.

The Solution That Worked

First, I moved the id’s of each section to a new element: (a span in this case)
<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>
The new <span> elements were added right above each section and would serve as the new anchor point. I’m not the biggest fan of empty elements on a page, but it does address the issue. Once the new <span> elements were in place, a bit of CSS was added:
.anchor{
  display: block;
  height: 115px; /*same height as header*/
  margin-top: -115px; /*same height as header*/
  visibility: hidden;
}
The height and margin-top numbers are based on the height of the header. Using the Chrome developer tools, this number is easy to figure out. After these simple adjustments, it was time to jump back in the browser and test it out. Clicking the anchor link jumped down the page and the <span> corrected the space for the header and voilà – The page now jumps correctly!

Discussion

  1. I searched for quite some time to find a fix for this problem and could not find nothing except js fixes. This solution worked amazingly well and was simple to impliment. Thank you so much!

  2. Torsten says:

    Thank you for this post. You solved my life :-) Worked nearly two hours to fix this problem

  3. Phillip Lovelace says:

    @Torsten – glad to help and thanks for the kind words!

  4. david says:

    hey, thanks for sharing – pretty cool solution, helped me a lot, i was going nuts with this issue :D

  5. pedro says:

    here you can check another approach that avoids the html editing. It just adds the “extra” element via css. It useful if you have a long list of elements.
    http://stackoverflow.com/questions/4086107/html-positionfixed-page-header-and-in-page-anchors

  6. Viktor says:

    This definitely solved the problem. Thanks a lot.

  7. Christian says:

    Great. Thanks a lot! This really helped me solve my problems.

  8. Tiago says:

    Very helpful, thanks!

  9. Shaw says:

    This was very helpful!

    I attempted to make something that worked with default anchor codes using the [name] selector and psuedo elements. Here’s what I’ve come up with so far: http://jsfiddle.net/shshaw/VujcA/

    Chrome & Safari work without a hitch, IE8 works mostly as expected, Firefox doesn’t like semantic anchors & IE7 is just gross.

    Anyone else willing to take a stab?

  10. David Myers says:

    Awesome, thanks for your help! This was exactly what I was looking for.

  11. JSV says:

    That was awesome help, thanks! I have been trying to figure this out for a couple of hours. Awesome!!

  12. Anchorproblems says:

    Thank you sooo much!! I wish I found your website earlier!

  13. Greg Blass says:

    Great idea. Implementing in our app. Cheers!

  14. Chandra says:

    Very Helpful, Thanks !

  15. Chandra says:

    Great, Helps lot !

  16. Sheckles says:

    Thank you, Mr. Lovelace – great fix! [applause]

  17. Patrick Haroldson says:

    Well, it sorta works…. what I want to do now is take the huge space out between each of my anchor points. it seems to put a header height space between each section, which is no good for what I am doing.

    here check it out: http://innovationlighting.net/rentals

  18. Patrick Haroldson says:

    oops, that is http://innovationlighting.net/rentals.php
    my bad…

  19. Phillip Lovelace says:

    Hi Patrick,

    I took a look at your site and it appears you are missing the negative margin and visibility css properties. Please try adjusting your CSS:

    .anchor {
    display: block;
    height: 213px;
    margin-top:-213px;
    visibility:hidden;
    }

    Hope that helps!

  20. shalini says:

    thank u so much.. helpful :)

  21. Vatta says:

    I have to salute you, these handful lines of code do the trick!

    I was close to completely going nuts before :-)

  22. John says:

    This is great. I’d been struggling with this for a while. Thank you

  23. Paul says:

    This is a good solution, I had not considered this before. I have had similar problems and found that adding padding to the div can also be effective as long as it works with the layout of your site.

  24. Lucas says:

    Really great! Solved my problem. Thank you!

  25. Vlad says:

    Great tips mate,thank you very much!

  26. Greetings! This is my first comment here so I just
    wanted to give a quick shout out and tell you I really enjoy reading through your articles.
    Can you recommend any other blogs/websites/forums that cover the
    same subjects? Thank you so much!

  27. Lee says:

    Watch out for the negative value, as with Patrick Haroldson, that caught me out too.

    Once the negative value is fixed, the gaps disappear. This works really well. Great work, Phillip, well done. And thank you.

  28. Madhvik says:

    Hye Philips

    This was truly a meaningful post. Three cheers to you man !!
    I was struggling for past 2 hours on this topic and was not able to find any clue on how to do it in simple measure. Your answers was Bull’s eye , straight to the goal.

    Thanks :)

  29. Vera says:

    THANK YOU!! I’d never figure out myself!

  30. Iván Melgrati says:

    Phillip, this saved me quite a bit of trouble… Gracias, amigo!!
    A new fan from Argentina

  31. Hey Iván – thanks for the kind words and I am glad you found it useful!!

  32. kevin says:

    Thanks!!!

  33. Amanda H says:

    Thank you so much for this!

  34. Lucas Saliés Brum says:

    Thank you!!!
    Works like a charm!
    :)

  35. Victor says:

    Thanks for the trick ! ;)

  36. Nick says:

    AWESOME. Seriously, I’ve been stuck with this same problem for days. Glad I found such a simple fix. THANK YOU!!!

  37. Taylor says:

    Thank you so so much! Trawled every corner of the internet for this fix!

  38. Kristijan says:

    Thank you kind sir, one correction though, for the sake of people that will copy-paste your code, please correct the commented part of the anchor css class like this:
    .anchor {
    display: block;
    height: 115px; /* same height as header */
    margin-top: -115px; /* same height as header */
    visibility: hidden;
    }

  39. Hey Kristijan – I’ve updated the code block and thanks for pointing that out.

  40. Tyler says:

    Thank you so much! You saved my life!

  41. Kristin says:

    This is exactly what I was looking for – I was struggling for a solution. Thank you for posting!!

  42. Adam says:

    Super helpful and i no longer am growing gray hair!!!

  43. Brock says:

    I, as well, have been searching for an intuitive solution for this problem, and this works like a dream. Thank you so much!

  44. Shailesh says:

    Thanks for sharing, helped

  45. Gediminas says:

    Thanks a lot of! it saved a lot of time and solved my problems at my new web page! thanx a lot!

  46. aidan says:

    Brilliant! cheers mate

  47. Ele says:

    Thank you, this was driving me nuts!

  48. Steven says:

    Yay, nice tidy solution that works perfectly!! Thanks!!!

  49. Matthew says:

    Thanks so much. Such an easy and simple fix, and yet something that did not occur to me.

  50. Jane Kent says:

    Thank you ever so much. Your gift of knowledge keeps on giving. I’ve spent too much time searching for a solution to this and yours was straightforward! Thanks for sharing!

  51. Mortaza says:

    I wanted to thank you for this awesome solution.
    I had the same problem working on a chm help file months ago.
    That time this it solved my problem, BUT now another
    problem emerged out of the HTML bag.
    and that’s when you have to refer to an inline position.
    I mean something like this for example:

    Something and Anything something else . . .

    This work around causes “something else” to be rendered to a new line and
    that’s another problem, that I believe is because of “display:block”.

  52. Mortaza says:

    Sorry for BAD output

    The example was:

    <p>Something and Anything <span id=”my-id”></span>something else . . . </p>

  53. Matthew says:

    Perfect! Thank you for this solution. Works just as I need it to.

  54. Anne Katzeff says:

    Great solution. Clean and simple. Thank you!

  55. Davey says:

    Thanks!

  56. Sam says:

    Thanks! This was driving me crazy and your solution is simple and effective. I’d be interested to know what a more “semantic” solution would be, without an empty span, but at this point I’m just happy to have it finally working.

    Thanks again.

  57. James says:

    Was pulling my hair out with this bug/issue. Thanks for the tip sir !! Worked like a charm.

  58. Worked perfectly. Thank you.

  59. Ramona says:

    You saved me with this article. Thanks so much. It worked perfectly. Note for mobile don’t forget to readjust your height for the size of the mobile menu.

  60. Matt says:

    This is FANTASTIC. Thank you for this elegant solution.

  61. Bruce says:

    This worked beautifully. Thank you.

  62. […] header at the top of webpage! Then I found an useful blog describing the issue I had in “anchor links with a fixed header” also providing a solution […]

  63. Bruce says:

    Bumped into the problem and a search found your thoughtful assistance. Thanks.

  64. Aleajactaest says:

    If you have the div in a column, change ‘display’ to inline block.
    display: inline-block;

  65. fabrigm says:

    doesn’t work for the first div! but thanks for the others :=)

  66. […] “anchor links with a fixed header“ […]

  67. Raphael says:

    Thank you so much!

  68. Iris says:

    Thanks, that saved my life. :)

  69. A_Flama says:

    Perfect! Simple, clean and efficient!

  70. Tina says:

    This was clear and very helpful. Thanks.

  71. Diane says:

    Hello
    Just wanted a say a huge thank you for this, I was beginning to think I would never work this one out without making a big mess. I can go away for Christmas now with a smile on my face, thank you so much.
    Diane

  72. Mangakania says:

    Your solution just saved my life, friend. Perfect. Thanks a big big bunch!

  73. caos says:

    .anchor{
    position:relative;
    display:block;
    top:-3.618em;
    height:0;
    width:0;
    visibility:hidden;
    }

    This will prevent unwanted layout “empty spaces”

  74. Tinu K Thomas says:

    Huge Thanks……..

  75. Sébastien says:

    The same bug appears when finding a page with Ctrl+F: the found text would be under the header.
    One have to search and then scroll a little bit up to see the highlighted result…
    Did you find a solution for this problem?

  76. nikoloz says:

    thank you man, you saved my day. good job :)

  77. Very nice! The only problem I have is when using the CSS :target selector. Now it will affect the invisible span instead of the invisible element. I guess it’s more a Javascript problem now. Good job anyway!

  78. Aubrey Kemme says:

    THANK YOU SO MUCH FOR THIS! I am a student new to coding and this saved my butt and easily solved my problem! ( :

  79. Filippo says:

    Good, worked for me

  80. CSHER says:

    Hi there,
    I have a menu item that links to an anchor. When I’m on the same page as the anchor and I click the menu item, it takes me to the place I want and nothing is hidden behind the fixed header. When I’m on a different page, however, and I click the same menu item, I’m taken to the place in the text but the top portion is hidden behind the fixed header. This means that the fix above (and any other fix I can think of) will work correctly if I’m coming from another page, but if I’m coming from the same page it will create a space at the top when I navigate to the anchor. Do you have any idea how to fix this?

  81. i1corner says:

    You are Superb !!! … .. Exactly 100% right what people says… It’s Works.. !.. Thanks A lots….. This had cause me headache for quite long time & now your solution is perfect & Excellent.. !

  82. aianjac says:

    thanks for these…

  83. John Payne says:

    Perfect, thank you for sharing this. I had to over compensate for size of the header if anyone else has the same issue.

  84. Bev says:

    Excellent and elegant solution – I was looking for the same thing, as I am doing a lot of one page templates with fixed headers – a big thanks from me as well!!!

  85. Sri says:

    Thank you, It worked great for me.

  86. Shakir says:

    excellent solution for me.
    thank you very much….

  87. james says:

    Works well! I used this to globally set anchors purely used as anchor points (have id but no href):

    a[id]:not([href]) {

    }

  88. Socrates says:

    Very helpful. Thanks for sharing!

  89. Marta says:

    Thank you, this is exactly what I needed :)

  90. Aashika Jain says:

    Hey its very nice solution. Helped very much. Saved my time. Thnx

  91. Syed Imran ali says:

    Ok i think i would love to say Thaaaaaaaaaaaaaanks. My client was eating my brain (like zombie) because of this issue.

  92. Losef says:

    Thank you, works great ! :)

  93. Carrie says:

    This is a great solution. One issue, what if you only want to use the ID Anchor for mobile devices? Thanks!

  94. Victor Hugo Bueno says:

    Amazing! :D

  95. ash says:

    Sorry, didn’t work straight out of the box, have a feeling its conflicting somewhere, I did not change any of your variables, simply placed the css in my css file, and the span tags above the section i wanted to anchor to, and when i clicked the menu item, the page just scrolled to the top. I can see this as a great solution, however it did not work for me :/

  96. Looler says:

    Ohhhhhh…!!!! FANTASTIC!!! Thank U very much, it’s realy good method!!!

  97. mmaged says:

    Very helpful, thanks!

  98. Kasper A says:

    I love you! Thank you!!

  99. Dylan says:

    Worked like a charm, thank you so much!

  100. Filip says:

    Thank you. You learned me something very useful.

  101. Eirini says:

    That was so helpful!! Thank you very much for sharing!

  102. Rafael says:

    Greaat! Thks man

  103. Tammy says:

    super helpful! thanks!

  104. Durga Prasad says:

    very very very helpful!!!!! Thank you boss.

  105. Depa says:

    Thanks so much!! Your solution worked perfectly :)

  106. Ratheesh says:

    Thanks!! Perfect Solution!!!

  107. Seoirse says:

    Works perfectly!
    After days of nothing a step forward thanks your advice! Thanks a million!!!!
    Tried with IE11, Firefox, Chrome, in a pc, and in Firefox, Opera, and Safari in a Mac : It’s work on all of them!

  108. Jan Ivar says:

    Awesome! Works perfectly :D

  109. Tim says:

    Awesome article and totally worked! Thank you so much!

  110. Ramon says:

    Thanks, works perfect.

  111. Christina says:

    OMG!! After spending an hour trying stuff from stack overflow that seemed overly complicated, this worked!!!

  112. Rich says:

    This screws up layout in firefox 41. It’s like it applied the negative margin to the parent element. Works in Chrome.

  113. Stephen R Elliott says:

    Still the best solution I’ve seen! (Chrome)

  114. Thanks Stephen, I’m glad you found it helpful!

  115. Gilbert says:

    Thanks, works perfect!

  116. Sangar82 says:

    Brutal! Muchas gracias!!

  117. Mulumba says:

    Thank you, worked like a charm!

  118. Hugh says:

    Thanks so much – great trick

  119. Mike says:

    Thanks. Nice, simple, elegant solution.

  120. Javed Khan says:

    Hi, I have tried this, but did’t work for me. When I click on the hyperlink ‘link’ e.g. ‘Partners’ to jump to the partner section, the “#partner” hashtag is added to the URL but the page does not load, I then click on the refresh button in the browser (chrome) and it loads. need some help. thank you.

  121. Jacob says:

    THANKS!!!! So simple… Also to make different on mobile you could add something like
    @media only screen and (max-width: 700px){
    .anchor{
    display: block;
    height: 80px; /*same height as header*/
    margin-top: -80px; /*same height as header*/
    visibility: hidden;
    }
    }
    See the result at my site @ http://sharkt.ca/services/local-seo-canada/ I’m currently doing a mobile version of my site so whit this CSS on top i get the exact result I want. THX a million time.

  122. Keith says:

    Thank you so much! My anchor links kept being hidden by the top fixed navigation areas, this was a perfect solution! You saved me HOURS!!

  123. Keke says:

    Did not work for me. I have vw values for basically everything. I can’t make the margin-top pull the span up, so it leaves extra space.

  124. Elizabeth says:

    Hi thank you for this. But it is not working for me. I am using the CSS editor within wordpress.org. I am wondering if that is having an effect? Let me know if you have any ideas

  125. martin says:

    Thanks Mate, thanks for posting that solution. Saved my day!

  126. Peter says:

    Hi why not trying:

    #myanchor {
    padding-top: 100px /* height of header */
    margin-top: -100px
    }

    It works great on my pages
    regards peter

  127. oziel says:

    I have a problem that I have the half fixed jejeje the anchor works perfectly as the way you helped us but…. It doesnt math when you put on the menu the #section… it does the same problem at the beggining, if you check my website you can discover what i am talking about, press “uno” in the menu at the top… but dont scroll down and you will see… but if you scroll down a bit and the you press “uno”it will match perfectly… do you know why?

  128. Daniele says:

    It worked! thanks so much

  129. Jean-Sébastien says:

    Nice trick! Just what I needed, thanks.

  130. Thanks! This worked great and only took a few media queries for all-device perfect viewing. :)

  131. Josh-Foster says:

    Thanks! This worked perfectly and probably saved me hours of headache; it’s so simple.

  132. Jerome says:

    You saved me :p
    thanks a lot !
    works perfectly

  133. Chinh Ngo says:

    Nice trick, it worked. Thanks.

  134. SRD says:

    Thank you so much. I’m going to be bookmarking your blog for further help.

  135. Nita Design says:

    Just the solution I was looking for. Nice and easy. Thank you

  136. Muralidhar Yaragalla says:

    This solution worked like a charm. Thank you so much.

  137. Tyler says:

    Thank you! This helped me BIG time.

  138. Jon says:

    Peter’s solution within the comments works when you’re unable to modify the markup, and removes the need for extra elements.

    https://pixelflips.com/blog/anchor-links-with-a-fixed-header#comment-162990

  139. Alberto says:

    I managed to make it work without span and ID….just adding a class “anchor” to the anchor name.

  140. gracious says:

    thanks :)

  141. Ferdi says:

    Thank you, it worked :)

  142. Kim says:

    Terrific solution, thank you!!

    To state the obvious, setting height/margin top at a value greater than that of the nav bar creates even more space. Love the simple customization.

  143. Ryan says:

    Thanks so much! Love this fix.

  144. Sean says:

    Awesome fix! Super quick and easy to implement. Saved me a lot of headache on my site.

  145. doubleUTF says:

    Yeah this workaround is simple and easy, thank you!

  146. Xzone9 says:

    This fix works without aditing any content on your pages:

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

  147. tm says:

    Thanks !!!!!! It working fine..

  148. Mike says:

    hi,
    it working not for the top anker. My menu is not working. I have scroll down a little, after that the menu works. If i go back to top it stops working again…
    any solutions?

  149. Jen says:

    Still the best resolution out there! Thanks!!

  150. zafire says:

    After an hour of playing around with JS i found this simply solution.
    Thanks alot!! <3

  151. Ernest says:

    Thank you so much!

  152. 444poon says:

    Many thanks to @caos ! Your CSS solves my problem.

    caos says:
    January 29, 2015 at 2:01 pm
    .anchor{
    position:relative;
    display:block;
    top:-3.618em;
    height:0;
    width:0;
    visibility:hidden;
    }

    This will prevent unwanted layout “empty spaces”

  153. fred says:

    :target:before {
    content:””;
    display:block;
    height:55px; /* fixed header height your height*/
    margin:1px 0 0; /* negative fixed header height */
    }

  154. fred says:

    no need for spans and other extra stuff, just add “space” on the fly

  155. Jessica says:

    Thanks so much. I’m just learning, and I couldn’t find any solutions that I actually understood.

  156. Thank you for sharing!

  157. Tania says:

    Thank you so much! Everything I had found was java, but this solution is just great!

  158. Crystal says:

    So, I this solution didn’t work for me… I am trying to find a solution where it doesn’t matter how tall the “fixed” element is but that the section always appears underneath it. I say this because this menu is expandable and will change heights based on different window sizes.

  159. Vevenia says:

    this is not work for me. try using it, but the format of text is not readability, its mean broke the text.

  160. Clahumoon says:

    Simplemente genial!! Thanks for that simple and brilliant!

  161. Lisa says:

    This worked beautifully. Thanks so much!

  162. Thabang says:

    Thanks a lot, simplest solution that works perfectly.

  163. Rebecca says:

    Thank you so much! you saved me a massive headache for mobile!!!!

  164. Clement says:

    You my brother are the definitions of genius

  165. Clement says:

    You my brother are the definition of genius

  166. Sree says:

    You saved my day…was going nuts with this issue :)

  167. Duncan says:

    Great!!!!!

  168. isa says:

    Excelente amigo, aun sigue funcionando perfecto .. gracias

  169. Claude says:

    Work great ! But one doubt regarding SEO. As anchor links are very usefull to give strength to the keyword used. would it be harmful for SEO to put the anchor on the wrong element (element above the position the anchor should be) ?
    Would be even better to use a trick to be able to keep the anchor position…

    I used your trick on my website.

    NB: in my case i had to adjust the sized of the invisible span to the screen (desktop or smartphone), and also to add an extra margin to the header (only once become sticky – as the relative position on the page move as well…)

    https://thailandfightgear.fr/questions-reponses-faq

  170. Bakari says:

    VICTORY!!! Thanks

  171. Jay says:

    Thanks a lot. You are a savior. Worked great.

  172. David says:

    Thank you!

  173. Jesse says:

    ingenuity = you

  174. Jack Mason says:

    Nice!
    On page links lining up nicely allowing for my header.
    Thank you for sharing your solution.

    Jack

  175. sugi says:

    Thank you for sharing this!

  176. Timo says:

    Thanks a lot. You saved me a lot of time!! :)

  177. Alex says:

    You rule! Much appreciated, this worked :)

  178. Marcus Stenberg says:

    Worked! Many thanks!!

Leave a Comment