While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or
edited it to ensure you have an error-free learning experience. It’s on our list, and we’re working on it!
You can help us out by using the “report an issue” button at the bottom of the tutorial.
There’s a new value in town for the CSS position property: sticky
. It allows us to make elements stick when the scroll reaches a certain point. An element with position: sticky
will behave like a relatively-positioned element until it reaches a specified point and then starts behaving like a statically-positioned element. In this post we’ll create a simple example to illustrate.
We’ll have a div
container that will be a flex container and then 4 additional div
elements that will be the flex items. Note we don’t have to use flexbox at all for position: sticky to work, here it’s just that flexbox happens to work great for our example.
Check our flexbox primer if you’d like a refresher on the different flexbox properties and values.
Here’s the simple markup:
<div class="container">
<div class="item punk">
<img src="https://www.digitalocean.com/images/punk.svg" width="100" alt="Item 1">
</div>
<div class="item pony">
<img src="/images/pony.svg" width="100" alt="Item 2">
</div>
<div class="item dino">
<img src="/images/dino.svg" width="100" alt="Item 3">
</div>
<div class="item steampunk">
<img src="/images/steampunk.svg" width="100" alt="Item 4">
</div>
</div>
And now our styles, with the important rules highlighted:
.container {
display: flex;
justify-content: space-around;
align-items: flex-start;
border: 2px dashed rgba(114, 186, 94, 0.35);
height: 400px;
background: rgba(114, 186, 94, 0.05);
}
.punk {
position: -webkit-sticky;
position: sticky;
top: 4rem;
}
.pony {
position: -webkit-sticky;
position: sticky;
top: 0;
}
.dino {
position: -webkit-sticky;
position: sticky;
bottom: 1rem;
align-self: flex-end;
}
And here’s the result. Try scrolling the page up and down to notice what happens:
If position: sticky is not working: There are two common scenarios where an element set to position: sticky;
won’t actually stick to the window as intended:
- No position property has been defined: Make sure the sticky element has
top
,bottom
set. Or in the case of horizontal scrolling,left
orright
.) - One of the element’s ancestors has incompatible
overflow
: If any of the parents above the sticky element have overflow (x or y) set tohidden
,scroll
orauto
, sticky will not work.
Conclusion
Here are a few additional things to note:
- With our example, the
align-items: flex-start
rule on the flex container is important because otherwise flex items default to a value ofstretch
where the elements would take the whole height of the container, cancelling the sticky effect. - We need to make use of the
-webkit-sticky
vendor prefix for it to work in Safari. - Notice how sticky-positioned elements are only sticky within their parent element.
- Browser support for
position: sticky
: As of 2020, 95% of browsers have some level of support. For details see Can I Use css-sticky