GitHub Download

One line CSS solution to prevent anchor links from scrolling behind a sticky or fixed header

A sticky or fixed menu is a very popular UX solution that displays a navbar at the top of the page to provide access to menu items at all times, even while scrolling pages. This simple addition can make it much easier for users to jump between your site content, especially on long-form pages.

However, while this method works well in general use, if a page uses anchors in the menu to allow users to instantly jump to specific sections of the page, we run into an issue. When an anchor is clicked, The page will scroll to position the anchor at the very top of the viewport, meaning that the section title and perhaps even part of the content will be obscured by the fixed menu.

Sticky header covering an anchor section
Sticky header covering an anchor section

So far, the standard solution has been to add top margin and padding to the anchor sections, but this has often resulted in a lack of control over the spaces, preventing fine-tuning of the page layout.

Fortunately, we have a new, simple, one-line CSS solution: scroll-margin-top and scroll-padding-top.

The scroll-padding-top property

The scroll-padding-top property is applied to the parent container and acts just like a CSS top padding, defining offsets from the top of the scrolling area.

scroll-padding-top: <value>; 

You can use any px, em, rem, vh, %, etc. value, as well as auto, where the user agent determines the offset as 0px.

Let see how it works

You could add the scroll-padding-top CSS property to an HTML element with a value of 4rem. Now when you click the anchor link, the browser jumps to the anchor section but leaves padding of 4rem at the top, rather than scrolling the anchor point all the way to the top. With this, when the height of the sticky menu is 3rem, the section the anchor point scrolls to will be wholly visible, separated from the sticky menu by that extra 1rem

<!doctype html>
<html>
<body>
  <nav>
     <ul>
        <li><a href="#anchor-1"> Menu link with anchor </a></li>
        <li><a href="#anchor-2"> Menu link with anchor </a></li>
        <li><a href="#anchor-3"> Menu link with anchor </a></li>
     </ul>
  </nav>
  <section id="anchor-1"> Your stuff here </section>
  <section id="anchor-2"> Your stuff here </section>
  <section id="anchor-3"> Your stuff here </section>
</body>
</html>
html {
  scroll-padding-top: 4rem;
}
nav {
  height: 3rem;
  position: sticky;
  top: 0;
}

That's it.

The scroll-margin-top property

The scroll-margin-top property, in simple terms, defines the top margin of the anchor sections (i.e. the container‘s children) that the browser will use when snapping the scrolled element into place.

scroll-margin-top: <value>; 

This property refers to the values defined with length units: px, em, rem, vh, etc.

The end result of using the scroll-margin-top property will be basically the same as when using scroll-padding-top, in that the scrolled section will be visible and separated slightly from the top of the viewport to allow room for the menu, but it achieves this result via a different method.

Let see how it works

The scroll-margin-top property should be applied to each anchor section, and these sections will then leave a margin of 4rem at the top.

<!doctype html>
<html>
<body>
  <nav>
     <ul>
        <li><a href="#anchor-1"> Menu link with anchor </a></li>
        <li><a href="#anchor-2"> Menu link with anchor </a></li>
        <li><a href="#anchor-3"> Menu link with anchor </a></li>
     </ul>
  </nav>
  <section id="anchor-1"> Your stuff here </section>
  <section id="anchor-2"> Your stuff here </section>
  <section id="anchor-3"> Your stuff here </section>
</body>
</html>
nav {
  height: 3rem;
  position: sticky;
  top: 0;
}
section {
  scroll-margin-top: 4rem;
}

What's important to remember with these properties is that they both apply only to scroll-snapping, so they do not affect the actual padding of the HTML element or the defined margin between anchor sections.

Browser support for these solutions is great, as you can see here: scroll-margin-topscroll-padding-top, so we can make use of them immediately with no ill-effects.

Subscribe

Get the latest Publii news, updates and more delivered directly to your email inbox

You can change your mind at any time by clicking the unsubscribe link in the footer of any email you receive from us, or by contacting us at contact@tidycustoms.net. By clicking below, you agree that we may process your information in accordance with our Privacy Policy.