How to make an element sticky even if they are multiple levels deep in the DOM tree
Making an element sticky with CSS is really simple nowadays, however things can get a bit messy when we have the element deep into the DOM tree. In this tutorial I'll show you how to make sure to stick your element to the parent container even if there are multiple other elements in between.
The basics
In order to make a sticky element there's only two things to keep in mind:
- First make sure the parent element contains a scroll
- Make sure the children is set as sticky and the position top is the one you need, typically
0px.
If you have something like this:
<div class="parent">
<div class="sticky">Sticky element</div>
</div>
The CSS is really simple and it always work great.
.parent {
height: 200px;
overflow-y: scroll;
border: 1px solid #ccc;
padding: 0 16px;
}
.sticky {
position: sticky;
top: 0;
background: white; /* optional: avoid text blending with background */
padding: 8px 0;
z-index: 10; /* optional: ensures it stays above other content */
}
Cool, this works great for simple apps, but the reality is that you might have some layouts with multiple layers of elements in between the parent and the sticky element. Consider the following example:
<div class="parent">
<div class="header">
<h1>Help</h1>
<div class="row">
<div class="sticky">Sticky content</div>
<div>Something else</div>
</div>
</div>
<p>Long content…</p>
</div>
Now our styles don't work anymore, all elements scroll and nothing is sticking to the parent. How can we fix it?
To make a sticky element work inside nested elements, we need to avoid any ancestor with overflow:hidden that could clip it. We need to ensure the parent has enough height to allow space for the sticky behavior. The depth of nesting doesn't matter, as long as no ancestor changes scrolling contexts.
We also need to make sure the ancestors have a visible overflow, this will allow them to expand pass the overflow and in return our sticky element will work, so make sure to set overflow: visible to all ancestors.
<style>
.visible {
overflow: visible; // This does the magic
}
</style>
<div class="parent">
<div class="header visible">
<h1>Help</h1>
<div class="row visible">
<div class="sticky">Sticky content</div>
<div>Something else</div>
</div>
</div>
<p>Long content…</p>
</div>
After adding that single line to all the ancestor the sticky element should start working again!
Did you like this post?
If you enjoyed this post or learned something new, make sure to subscribe to our newsletter! We will let you know when a new post gets published!