I am trying to create a layout where the page height is fixed to the viewport (100vh), the .sidebar and .content areas scroll independently, and a .content-header inside .content should stay sticky while the .content-body scrolls.
Here is the CSS I am using:
body {
margin: 0;
height: 100vh;
display: flex;
flex-direction: column;
}
.page-header {
flex: 0 0 auto;
padding: 1rem;
background: #333;
color: white;
}
.layout {
flex: 1 1 auto;
display: grid;
grid-template-columns: 250px 1fr;
max-height: 100%;
overflow: hidden; /* needed so main area does not scroll the whole page */
}
.sidebar {
overflow-y: auto;
padding: 1rem;
background: #f1f1f1;
}
.content {
overflow-y: auto; /* scroll only this area */
padding: 1rem;
}
/* Sticky header inside the scrollable content area */
.content-header {
position: sticky;
top: 0;
padding: 0.5rem 0;
background: white;
border-bottom: 1px solid #ccc;
z-index: 1;
}
.content-body {
padding-top: 1rem;
}
Expected behavior:
The whole page height is fixed to the viewport (
100vh);Only
.sidebarand.contentshould scroll;Inside
.content, the.content-headershould remain sticky at the top while.content-bodyscrolls underneath it.
However, position: sticky is not working inside the grid layout with overflow: hidden.
Why is this happening, and how can I keep the header sticky while allowing the content to scroll?
.layout { ... height: 100%; } .content { ... position: relative; }if you need.layoutto haveoverflow: hidden, you must ensure that.contentitself is an independent scroll container so that sticky is calculated within it.