Explain Codes LogoExplain Codes Logo

Fixed page header overlaps in-page anchors

html
responsive-design
css-variables
javascript
Nikita BarsukovbyNikita Barsukov·Feb 7, 2025
TLDR

Avoid anchor overlap with a fixed header using a CSS pseudo-element to offset the anchor point. Here's the required stylesheet snippet:

.anchor::before { content: ''; /* No kid, this isn't Harry Potter's invisible cloak */ display: block; height: 0; margin-top: -100px; /* Header's height - our magic number */ padding-top: 100px; /* Same thickness of said header */ visibility: hidden; /* But it's magically invisible */ pointer-events: none; }

Bind .anchor to elements linked. Negative margin-top moves the element up while padding-top pushes it back down, making it visible below the header when linked. Personalize both values to your header's height for a butter-smooth anchor transition.

Responsive Controls & Cross-Browser Support

Responsive Designs: Adapt to Device Changes

Considering responsive designs, using relative units (em) for headers' dimensions and offset calculations ensures consistency across screen sizes and font settings.

.anchor::before { margin-top: calc(-1 * var(--header-height)); /* Putting header height under CSS variable, because, well, variables are cool */ padding-top: var(--header-height); }

Provided in your root CSS, define --header-height:

:root { --header-height: 5em; /* Feel free to replace 5em with the size of your favorite chocolate bar */ }

For viewport adaptability, these offsets can dynamically adjust by using JavaScript paired with media queries to modify --header-height.

Browser Compatibility: Ensure Smooth Surfing

While scroll-margin-top and scroll-padding-top are flaunted by modern browsers, having a fallback for older browsers is indeed a gentleman's move. Here's an exemplar JavaScript to calculate and add an offset to the scroll position:

window.addEventListener('hashchange', function() { var fixedHeaderHeight = document.querySelector('.fixed-header').offsetHeight; window.scrollTo(window.scrollX, window.scrollY - fixedHeaderHeight); /* We aren't scrolling for donuts */ });

High-Precision Positioning

Offset Controls & Transparent Spacers: Mastering Layouts

The scroll-padding-top CSS property is a precision ninja for offsetting scroll positions. Embrace it.

:root { scroll-padding-top: var(--header-height); /* Your keyboard also needs a reason to dance */ }

A transparent spacer div is another trusted sidekick. It aids in visual offsets.

<div class="spacer" style="height: 100px;"></div><!-- Same as the height of your secret sandwich stash -->

Enter the world of divs. Nest them and place anchors within divs styled with position: relative and a negative top of the header's height:

<div class="anchor-container" style="position: relative; top: -100px;"></div> /* Negative top? Probably an Introvert value */

Precision With Semantic HTML and IDs

Keep different IDs for your anchors and linked sections. Promote harmony among CSS styles and precision targeting:

<a href="#section1">Section 1</a> ... <div id="section1-anchor" class="anchor"></div> <section id="section1">Content of Section 1</section>

A semantic HTML structure nurtures automatic outline generation, accessibility, and inadvertently sidesteps overlapping troubles.

Master Scroll Behavior

Controlling Scroll Stop and Scroll Offset

The scroll-snap-type controls destination post scroll, enhancing in-page navigation.

Combine scroll-snap-type with JavaScript to add a smooth offset accounting for the fixed header:

document.querySelector('.anchor').addEventListener('click', (e) => { e.preventDefault(); let target = document.querySelector(e.target.getAttribute('href')); let headerOffset = document.querySelector('.fixed-header').offsetHeight; /* No, this isn't your Harry Potter invisibility cloak */ let elementPosition = target.offsetTop; /* Offset top — not the location of the treasure chest */ window.scrollTo({ top: elementPosition - headerOffset, /* Subtract the magic number */ behavior: 'smooth' /* Like butter */ }); });