Menu
I have a fixed menu bar at the top of my page, say it’s 100px high.
In that menu I have links to content down the page, how can I get the anchor links to bring the content to the bottom of my menu bar.
<a href=”#sectionThree”>This Link</a>
<section id=”sectionThree”></section>
Currently it goes to the top of the window however my position fixed menu bar cover it.
Padding-top:100px; works but when scrolled it has a weird 100px white spce.
``<i>
</i><!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>One Page Layout</title>
<style>
html,
body {
height: 100%;
}
body {
margin: 0;
display: flex;
flex-direction: column;
font-family: arial;
}
header {
flex: 0 0 auto;
}
main {
flex: 1;
overflow-y: auto;
}
main>section {
height: 100%;
}
footer {
font-size: 2em;
}
/* Nav */
nav ul {
list-style: none;
display: flex;
flex-direction: row;
}
nav ul li {
padding: 0.5em;
}
</style>
</head>
<body>
<header>
<nav>
<ul>
<li>
<a href="#section1">Home</a>
</li>
<li>
<a href="#section2">Page 1</a>
</li>
<li>
<a href="#section3">Page 2</a>
</li>
<li>
<a href="#section4">Page 3</a>
</li>
</ul>
</nav>
</header>
<main>
<section id="section1">
Lorem ipsum dolor sit amet, ...
</section>
<section id="section2">
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu
feugiat ...
</section>
<section id="section3">
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer
possim assum...
</section>
<section id="section4">
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus
est Lorem ipsum dolor sit amet ...
</section>
</main>
<footer>This is the footer</footer>
</body>
</html><i>
</i>
``
``<i>
</i><!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>One Page Layout, Sticky Nav</title>
<style>
body {
margin: 0;
display: flex;
flex-direction: column;
font-family: arial;
}
nav {
position: sticky;
top: 0;
}
main>section {
/* height: 100%; */
height: 80vh;
}
footer {
font-size: 2em;
}
/* Nav */
nav ul {
list-style: none;
display: flex;
flex-direction: row;
}
nav ul li {
padding: 0.5em;
}
</style>
</head>
<body>
<header>
<p>This is the content above</p>
<p>More content above</p>
</header>
<nav>
<ul>
<li>
<a href="#section1">Home</a>
</li>
<li>
<a href="#section2">Page 1</a>
</li>
<li>
<a href="#section3">Page 2</a>
</li>
<li>
<a href="#section4">Page 3</a>
</li>
</ul>
</nav>
<main>
<section id="section1">
Lorem ipsum dolor sit amet, ...
</section>
<section id="section2">
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu
feugiat ...
</section>
<section id="section3">
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer
possim assum...
</section>
<section id="section4">
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus
est Lorem ipsum dolor sit amet ...
</section>
<footer>This is the footer</footer>
</main>
<script>
const
menu = document.querySelector('nav'),
menuBox = menu.getBoundingClientRect(),
// vertical space the menu or nav takes:
hSpace = menuBox.height;
document.addEventListener('click', event => {
// was a link in the nav clicked?
if (event.target.matches('nav a')) {
// prevent default action for this link:
event.preventDefault();
const
// get element we have to scroll to:
ele = document.querySelector(event.target.getAttribute('href')),
// get top position of the element relative to the viewport:
offsetEle = ele.getBoundingClientRect().top
// we have to add the scroll position in order to get
// the element's position relative to the document:
+ document.documentElement.scrollTop,
// space the menu requires has to be subtracted
// from the top offset of the element related to the document:
scrollAmount = offsetEle - hSpace;
document.documentElement.scrollTop = scrollAmount;
}
});
</script>
</body>
</html><i>
</i>
``
``<i>
</i><body>
<header class="non-sticky">
<p>Non-sticky content above</p>
<p>More content above</p>
</header>
<header class="sticky">
<h1>The Headline Inside Sticky Header</h1>
More content inside sticky header
<nav>
<ul>
<li>
<a href="#section1">Home</a>
</li>
<li>
<a href="#section2">Page 1</a>
</li>
<li>
<a href="#section3">Page 2</a>
</li>
<li>
<a href="#section4">Page 3</a>
</li>
</ul>
</nav>
</header>
<main><i>
</i>
`</CODE>
Then make this container sticky:
<CODE>
`<i>
</i> header.sticky {
position: sticky;
top: 0;
}<i>
</i>
`</CODE>
And adjust the javascript:
<CODE>
`<i>
</i> const
stickyHeader = document.querySelector('header.sticky'),
stickyHeaderBox = stickyHeader.getBoundingClientRect(),
// vertical space the menu or nav takes:
hSpace = stickyHeaderBox.height;
document.addEventListener('click', event => {
// was a link in the nav clicked?
if (event.target.matches('nav a')) {
// prevent default action for this link:
event.preventDefault();
const
// get element we have to scroll to:
ele = document.querySelector(event.target.getAttribute('href')),
// get top position of the element relative to the viewport:
offsetEle = ele.getBoundingClientRect().top
// we have to add the scroll position in order to get
// the element's position relative to the document:
+ document.documentElement.scrollTop,
// space the menu requires has to be subtracted
// from the top offset of the element related to the document:
scrollAmount = offsetEle - hSpace;
document.documentElement.scrollTop = scrollAmount;
}
});<i>
</i>
``
``<i>
</i><header class="non-sticky">
Content is not sticky
</header>
<header class="sticky">
First block of sticky content
</header>
<section class="non-sticky">
Another block which is not sticky
</section>
<section>
Second block of sticky content
</section><i>
</i>
``
``<i>
</i> <header class="non-sticky">
<p>Non-sticky content above</p>
<p>More content above</p>
</header>
<h1 class="sticky">Sticky Headline</h1>
<section class="non-sticky">
<p>More non-sticky content</p>
</section>
<nav class="sticky">
<ul>
<li>
<a href="#section1">Home</a>
</li>
<li>
<a href="#section2">Page 1</a>
</li>
<li>
<a href="#section3">Page 2</a>
</li>
<li>
<a href="#section4">Page 3</a>
</li>
</ul>
</nav><i>
</i>
`</CODE>
JS:
<CODE>
`<i>
</i> const
sticky1 = document.querySelector('h1.sticky'),
sticky1Box = sticky1.getBoundingClientRect(),
sticky2 = document.querySelector('nav.sticky'),
sticky2Box = sticky2.getBoundingClientRect(),
// vertical space the menu or nav takes:
hSpace = sticky1Box.height + sticky2Box.height;
// sticky position for 2nd sticky element:
sticky2.style.position = 'sticky';
sticky2.style.top = sticky1Box.height + 'px';
// not modified below this line:
document.addEventListener('click', event => {
// was a link in the nav clicked?
if (event.target.matches('nav a')) {
// prevent default action for this link:
event.preventDefault();
const
// get element we have to scroll to:
ele = document.querySelector(event.target.getAttribute('href')),
// get top position of the element relative to the viewport:
offsetEle = ele.getBoundingClientRect().top
// we have to add the scroll position in order to get
// the element's position relative to the document:
+ document.documentElement.scrollTop,
// space the menu requires has to be subtracted
// from the top offset of the element related to the document:
scrollAmount = offsetEle - hSpace;
document.documentElement.scrollTop = scrollAmount;
}
});<i>
</i>
``
0.1.9 — BETA 4.25