Останнім часом я вже давно не зустрічав сайтів, які мають статичний header. Практично всі фіксують його вгорі вікна. Щонайменше дуже зручно, коли навігація сайтом завжди знаходиться під рукою. Але є один момент, який може спричинити дискомфорт за такого підходу – це якірні посилання. Зазвичай під час кліка на таке посилання, секція із зазначеним Id опиняється вгорі вікна браузера. І якщо header у нас має position: fixed, то, отже, він буде перекривати частину контенту секції:

Є багато способів нівелювати цю проблему. У цій статті я запропоную відносно універсальний спосіб. У ньому ми будемо також враховувати якірні посилання, які можуть знаходитися на різних сторінках.
Готовий приклад: https://codepen.io/jecosjmecos/pen/jORmQeg
Трохи детальніше зупинимося на js коді:
document.addEventListener('DOMContentLoaded', function() {
// Moving to anchor on page load
scrollToAnchor();
// Move to anchor when clicking on anchored links
const headerLinks = document.querySelectorAll('a[href*="#"]');
headerLinks.forEach(function(link) {
link.addEventListener('click', function(event) {
if(event.target.pathname === window.location.pathname){
event.preventDefault();
let hash = this.getAttribute('href').split('#')[1];
scrollToAnchor('#' + hash);
}
});
});
});
function scrollToAnchor(hash = window.location.hash) {
if(hash.length > 1){
let headerHeight = document.querySelector('header').offsetHeight,
targetElement = document.querySelector(hash);
if(targetElement) {
var targetOffset = targetElement.offsetTop - headerHeight;
window.scrollTo({
top: targetOffset,
behavior: 'smooth'
});
}
}
}
Тут ми маємо функцію scrollToAnchor
. Як аргумент ми поміщаємо в неї id секції, яку нам необхідно буде показати у вікні браузера. За замовчуванням ми будемо брати цей id з url поточної сторінки (window.location.hash
).
function scrollToAnchor(hash = window.location.hash) {
if(hash.length > 1){
let headerHeight = document.querySelector('header').offsetHeight,
targetElement = document.querySelector(hash);
if(targetElement) {
var targetOffset = targetElement.offsetTop - headerHeight;
window.scrollTo({
top: targetOffset,
behavior: 'smooth'
});
}
}
У цій функції визначаємо висоту нашого header і перевіряємо наявність елемента з потрібним id. Якщо такий присутній, ми визначаємо координати секції з урахуванням висоти header і плавно скролимо до неї.
Викликати функцію ми будемо двічі. Один раз під час завантаження сторінки:
// Moving to anchor on page load
scrollToAnchor();
Другий раз при кліці на посилання в меню шапки:
// Move to anchor when clicking on anchored links
const headerLinks = document.querySelectorAll('a[href*="#"]');
headerLinks.forEach(function(link) {
link.addEventListener('click', function(event) {
if(event.target.pathname === window.location.pathname){
event.preventDefault();
let hash = this.getAttribute('href').split('#')[1];
scrollToAnchor('#' + hash);
}
});
});