0

Let's say I have a navbar like the following:

* {
  box-sizing: border-box;
}

html,
body {
  width: 100%;
  height: 100vh;
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  justify-content: center;
}

.container {
  width: 100px;
  height: 100%;
  transform: translateX(50px);
  /* An example transform (I can't use position: fixed) */
  background-color: green;
  overflow-y: scroll;
}

.navbar {
  width: 100%;
  height: 50px;
  background-color: rgba(255, 255, 0, 0.5);
  top: 0;
}

.navbar.sticky {
  position: -webkit-sticky;
  position: sticky;
}

.navbar.fixed {
  position: fixed;
}
<div class="container">
  <div class="navbar sticky">
  </div>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
</div>

As you can see before scrolling, the sticky navbar is initially above the content paragraphs. However, if the navbar class is changed from sticky to fixed, then the navbar does overlay the content (like I want), but it does not scroll with the container, since it is transformed.

How do I force sticky navbar to place the content after it underneath it so that it always behaves like an overlay to the content after it?

If the above isn't possible, then how do I force a fixed navbar to scroll with the user in a transformed container? Note that I want to avoid something similar to this answer (which is what I am currently using), because it results in jittery movements on the fixed container when scrolling.

Arnav Borborah
  • 9,956
  • 4
  • 32
  • 69
  • You'd need JS to switch `sticky` to `fixed` once the conditions are met. CSS can't do that,. – Paulie_D Aug 23 '19 at 14:45
  • @Paulie_D So there's no way for a position: sticky object to initially be on top of the content after it? – Arnav Borborah Aug 23 '19 at 14:49
  • No...sticky doesn't overlay content as such AFAIK nor is it intended to. – Paulie_D Aug 23 '19 at 14:53
  • @Paulie_D that's... unfortunate. Is there any alternative with position: fixed that doesn't require me to constantly update the navbars position with JS? – Arnav Borborah Aug 23 '19 at 14:55
  • unless you set a negative `margin-top` of the sticky navs height to the first element after the nav (`.navbar + * { margin-top: -50px;}`). but probably not ideal – zgood Aug 23 '19 at 14:55

1 Answers1

1

Subtracting the height of the navbar from the navbar with margin-bottom will work.

* {
  box-sizing: border-box;
}

html,
body {
  width: 100%;
  height: 100vh;
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  justify-content: center;
}

.container {
  width: 100px;
  height: 100%;
  transform: translateX(50px);
  /* An example transform (I can't use position: fixed) */
  background-color: green;
  overflow-y: scroll;
}

.navbar {
  --navbarheight: 50px;
  width: 100%;
  height: var(--navbarheight);;
  background-color: rgba(255, 255, 0, 0.5);
  top: 0;
}

.navbar.sticky {
  position: -webkit-sticky;
  position: sticky;
  margin-bottom: calc(0px - var(--navbarheight)); /* or -50px in other words */
}

.navbar.fixed {
  position: fixed;
}
<div class="container">
  <div class="navbar sticky">
  </div>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
  <p>Content</p>
</div>
Arnav Borborah
  • 9,956
  • 4
  • 32
  • 69
JRoss
  • 1,197
  • 7
  • 18