Reputation: 39
I added a sticky header and a smooth scrolling effect, and I cannot figure out how to fix the position so it counts with the header size. The things I have tried disable the sticky header completely.
I have tried to use several different techniques, although I am a newbie and it might be too hard for me to do by myself.
<div id="container">
<section id="sectionHome">
<!--Header and Logo-->
<header id="myHeader">
<logo>
<img src="Pictures/Marvel-logo-880x660.crop.png">
</logo>
</header>
<!--The Top Navigation Menu-->
<div id="mainNav">
<ul>
<li class="current"><a href="#">Home</a></li>
<li><a href="#firstArticle">Characters</a></li>
<li><a href="#secondArticle">Movies</a></li>
<li><a href="#thirdArticle">More Info</a></li>
</ul>
</div>
</section>
//Smooth Scrolling in Main Nav
$(document).ready(function() {
$('#mainNav li a').click(function(e) {
var targetHref = $(this).attr('href');
$('html, body').animate({
scrollTop: $(targetHref).offset().top
}, 1000);
e.preventDefault();
});
});
// Sticky Header
window.onscroll = function() {
myFunction()
}; // When the user scrolls the page
var header = document.getElementById("sectionHome"); // Get the header and top nav
var sticky = header.offsetTop; // Get the offset position of the navbar
function myFunction() { // Add the sticky class to the header when you reach its scroll position. Remove "sticky" when you leave the scroll position
if (window.pageYOffset > sticky) {
header.classList.add("sticky");
} else {
header.classList.remove("sticky");
}
}
This was one thing I tried, but it disabled my sticky header:
$(document).ready(function() {
var headerHeight = $('header').outerHeight(); // Target your header navigation here
$('#main-nav li a').click(function(e) {
var targetHref = $(this).attr('href');
$('html, body').animate({
scrollTop: $(targetHref).offset().top - headerHeight // Add it to the calculation here
}, 1000);
e.preventDefault();
});
});
I thought I could set a value for the total header size and position it that way, although it disables the sticky header. How do I do this properly?
This is my webpage: http://www.student.city.ac.uk/~aczc972
Best regards, Danielle
Upvotes: 2
Views: 2965
Reputation: 919
I have added a sandbox how to do it using jQuery, generally speaking only one addition from my site is that I am checking what is the target e.g. scroll to top page, and if yes, I am running specified code for it:
if (targetHref === "#") {
$("html, body").animate(
{ scrollTop: 0 },
"1000"
);
} else {
$("html, body").animate({scrollTop: $(targetHref).offset().top},1000);
}
Subtract header height scroll to prevent covering content by header
scrollTop: $(targetHref).offset().top - 180"
Upvotes: 1
Reputation: 919
You can also scroll to top of the page like:
Add id="home"
to body and change href in:
<li class="current"><a href="#">Home</a></li>
to home
i.e.
<li class="current"><a href="#home">Home</a></li>
Should work with your code
Upvotes: 1
Reputation: 6467
This is not necessarily the best way to do this, but it's an example which is designed to illustrate how it can be done. You don't need jQuery to achieve this effect so it's worth trying it without.
The code below fixes the header, and adjusts the padding of the main wrapper to account for the size of the header. It then sets up listeners on elements with the class section-link
. For those elements, the click event will scroll to the element with the id which corresponds to the data-section
attribute for the element which was clicked.
You can ignore the css for this which was only added to illustrate how this might work.
const padForHeader = () => {
// find out how high the header element is
const headerHeight = document.getElementById('top-header').clientHeight;
// how much extra padding would we like?
const headerPadding = 20;
// add the two together to see how much padding we need to add
const headerBufferSize = headerHeight + headerPadding;
// set the marginTop property so that the header doesn't overlay content
document.querySelector('.wrapper').style.marginTop = `${headerBufferSize}px`;
};
padForHeader();
// when the window resizes, re-pad for the header
window.addEventListener('resize', padForHeader);
document
.querySelectorAll('.section-link')
.forEach(element => {
// we want to scroll 'smoothly' to the element
const scrollOptions = {
behavior: "smooth"
};
// we can read the data attribute to find the matching element's id
const elementIdToScrollTo = element.dataset.section;
// we can use the id we found to get the corresponding element
const elementToScrollTo = document.getElementById(elementIdToScrollTo);
// we can set the onclick property to scroll to the element we found
element.onclick = () => elementToScrollTo.scrollIntoView(scrollOptions);
});
.header {
background-color: red;
border: solid 2px grey;
border-radius: 5px;
font-family: arial;
margin: 0 auto;
position: fixed;
top: 0;
left: 0;
right: 0;
width: 97%;
}
.header>ul {
list-style: none;
color: rgba(250, 250, 240, 0.8);
}
.header>ul>li {
cursor: pointer;
display: inline-block;
position: relative;
top: 0px;
transition: all 0.3s ease;
width: 200px;
}
.header>ul>li:hover {
color: rgba(250, 250, 240, 1);
top: -1px;
}
.section {
background-color: rgba(20, 20, 30, 0.2);
height: 80vh;
border-bottom: solid 2px black;
padding-top: 50px;
}
<div class="wrapper">
<div id="top-header" class="header sticky">
<ul>
<li class="section-link" data-section="1">Item 1</li>
<li class="section-link" data-section="2">Item 2</li>
<li class="section-link" data-section="hello-world">Item hello world</li>
</ul>
</div>
<div id="1" class="section">
Test 1
</div>
<div id="2" class="section">
Test 2
</div>
<div id="hello-world" class="section">
Test 3
</div>
</div>
Upvotes: 0