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>
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)