Making Elements Stick in CSS Using position: sticky

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="/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:

Punk Sammy Pony Sammy Dino Sammy Steampunk Sammy

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:

  1. No position property has been defined: Make sure the sticky element has top, bottom set. Or in the case of horizontal scrolling, left or right.)
  2. One of the element’s ancestors has incompatible overflow: If any of the parents above the sticky element have overflow (x or y) set to hidden, scroll or auto, 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 of stretch 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