A different approach from the suggestions provided by others would involve overriding the default scrolling behavior of the browser when navigating to anchors. Instead, you can calculate the scrolling action based on the target element's offset from the top of the page using the .offset().top
method, and adjusting for the height of a fixed header element.
Consider the following HTML structure:
<header>
Fixed header.
<a href="#head1">Heading 1</a>
<!-- additional headers -->
</header>
<h1 id="head1">Heading 1</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vel dictum nulla. Pellentesque tincidun</p>
<!-- more content -->
The JavaScript implementation can be a bit complex. Firstly, check if the URL contains a hash, and if so, call a function to adjust the page scroll position. Otherwise, listen for click events on internal anchors using the selector a[href^="#"]
. The function should perform the following tasks:
- Retrieve the ID of the target element (from
window.location.hash
or the href
attribute)
- Calculate the vertical offset of the target from the top using
.offset().top
- Scroll the viewport manually to the calculated position, accounting for the fixed header height (you can use
.height()
or a fixed value like 75
)
Combining the steps above, you can use the following script:
$(function() {
// Define scroll position modifier
var scrollPos = function(targetID) {
var targetOffset = $(targetID).offset().top;
$(window).scrollTop(targetOffset - $('header').height());
};
// Update scroll position if hash is present in the URL
if(window.location.hash) {
// Remove '#' at the beginning with .substring(1)
scrollPos(window.location.hash.substring(1));
}
// Update scroll position on anchor click
$('a[href^="#"]').click(function(e) {
// Prevent default scrolling behavior
e.preventDefault();
// Update scroll position manually
scrollPos($(this).attr('href'));
});
});
View the fiddle for a demonstration: http://jsfiddle.net/teddyrised/u11011jc/