demian-wolf
demian-wolf

Reputation: 1858

How to make a sticky navbar without JS?

I want to create a sticky navbar. It should float over the content during scrolling, and should be displayed before the content if the page is scrolled to the top.

My implementation has almost worked but the part of the content was overlapped by the navbar when the page was scrolled to the top.

I managed to get it to work with JS by updating the padding-top CSS property of #content every time the window size is changed (see the fixContentPadding function).

Can this be done without JS?

Here is an example:

function fixContentPadding() {
  const navbarElement = document.getElementById("navbar");
  const contentElement = document.getElementById("content");

  contentElement.style.paddingTop = navbarElement.offsetHeight + "px";
}

document.addEventListener("resize", fixContentPadding);
document.addEventListener("DOMContentLoaded", fixContentPadding);
#navbar {
  position: fixed;
  top: 0;
  z-index: 1;
  width: 100%;
  background: lightblue;
}

#content {
  min-height: 200vh;  /* to demonstrate scrolling */
  border: 1px solid lightblue;
}
<div id="navbar">
  <a href="/">Hello, World!</a>
</div>

<div id="content">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>

Upvotes: 0

Views: 7416

Answers (3)

ray
ray

Reputation: 27245

This is what position: sticky is for:

#navbar {
  position: sticky;
  top: 0;
  background: aliceblue;
}
<div id="navbar">
  <a href="/">Hello, World!</a>
</div>

<div id="content-container">
  <div id="content">
    <p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p>
  </div>
</div>

Upvotes: 6

tacoshy
tacoshy

Reputation: 13002

function fixContentPadding() {
  document.getElementById("content-container").style.paddingTop = document.getElementById("navbar").offsetHeight + 15 + "px";
}
window.onresize = fixContentPadding;
fixContentPadding();
#navbar {
  width: 100%;
  height: 3em;
  background-color: lightblue;
  color: white;
  position: fixed;
  top: 0;
  z-index: 1;
}

#navbar *:hover {
  background-color: #2196F3;
  border-radius: 32px;
}

#navbar * {
  float: left;
  text-decoration: none;
}

#content {
  width: 90%;
  margin: 3em auto auto auto;
  word-wrap: break-word;
  padding: 0.01em 16px;
  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12)
}
<div id="navbar">
  <a href="/">Hello, World!</a>
</div>

<div id="content-container">
  <div id="content">
    <p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p>
  </div>
</div>

add a margin-top to the content div equal or alrger of the navbar hight.

Upvotes: 1

SKJ
SKJ

Reputation: 2326

A margin-top on your div#content-container ?

#navbar {
  width: 100%;
  background-color: lightblue;
  color: white;
  top: 0;
  position: fixed;
  z-index: 1;
}

#navbar *:hover {
  background-color: #2196F3;
  border-radius: 32px;
}

#navbar * {
  float: left;
  text-decoration: none;
}

#content-container {
  margin-top:40px;
}

#content {
  width: 90%;
  margin: auto;
  word-wrap: break-word;
  padding: 0.01em 16px;
  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12)
}
<div id="navbar">
  <a href="/">Hello, World!</a>
</div>

<div id="content-container">
  <div id="content">
    <p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p><p>Hello, World!</p>
  </div>
</div>

Upvotes: 1

Related Questions