1

I want my .sidebar flex element to be sticky when I'm scrolling but position: sticky; top: 0; doesn't work.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 100vh;
}

header {
  width: 100%;
  height: 100px;
  background-color: blue;
  opacity: 0.5;
  position: sticky;
  z-index: 100;
  top: 0;
}

.container {
  display: flex;
  gap: 2rem;
  position: relative;
}

.sidebar {
  position: sticky;
  top: 0;
}

.main {
  display: flex;
  gap: 2rem;
  flex-direction: column;
}

.main div {
  width: 300px;
  aspect-ratio: 1 / 1;
  background-color: red;
}
<div class="root">
  <header></header>
  <div class="container">
    <div class="sidebar">
      <p>Sidebar</p>
      <button>Upload image</button>
    </div>
    <div class="main">
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </div>
  </div>
</div>
web-tiki
  • 99,765
  • 32
  • 217
  • 249
  • The problem is related with flex box. Check this answer: https://stackoverflow.com/a/44446672/2007927 – george Jan 09 '23 at 10:38

1 Answers1

3

The issue is that the default property of align-items for flex elements is normal (acts like stretch in this context) therefore the .sidebar element takes all the available height and can't have the "sticky effect".
You can achieve the the sticky efect by changing the align-items property on the .container element to flex-start like this :

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 100vh;
}

header {
  width: 100%;
  height: 100px;
  background-color: blue;
  opacity: 0.5;
  position: sticky;
  z-index: 100;
  top: 0;
}

.container {
  display: flex;
  align-items: flex-start; /* <- ADD THIS */
  gap: 2rem;
  position: relative;
}

.sidebar {
  position: sticky;
  top: 100px;
}

.main {
  display: flex;
  gap: 2rem;
  flex-direction: column;
}

.main div {
  width: 300px;
  aspect-ratio: 1 / 1;
  background-color: red;
}
<div class="root">
  <header></header>
  <div class="container">
    <div class="sidebar">
      <p>Sidebar</p>
      <button>Upload image</button>
    </div>
    <div class="main">
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </div>
  </div>
</div>

(Note that I also changed the top property on the .sidebar element so it doesn't hide under the header)

web-tiki
  • 99,765
  • 32
  • 217
  • 249