A Sticky Situation (position sticky in CSS)
Tags: css, webdev, frontend
Published: 2020-10-06 10:37:24

Many months ago,  I was finding myself implementing a sticky navigation bar using vanilla JS. Not because I didn't know about `position: sticky;` but because I needed to support IE11 (😢). So while this initially kept me from checking it out more closely, it made me even happier once I was finally able to use it later on.

This post is a short primer on what the `sticky` value is and where you might find it useful when implementing designs and layouts.

## What is sticky?

![Man jumping and sticking on a wall](https://media.giphy.com/media/xTiN0ByzdgHIjqZBzq/giphy.gif)

`sticky` is one of the 5 values the `position` property can use as a keyword. Taking a look at the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/CSS/position), we can learn that:

> _"The element is positioned according to the normal flow of the document, and then offset relative to its nearest scrolling ancestor and containing block (nearest block-level ancestor), including table-related elements, based on the values of top, right, bottom, and left. The offset does not affect the position of any other elements."_

Let's simplify this statement a bit.

When using the keyword `sticky`, you have to specify at least one of the 4 following properties: `top`, `right`, `bottom` or  `left`. In simplified terms, these values then determine the "offset" of the sticky behavior, meaning when the stickiness should start.

Let's take a look at a common use case to see how we would use the `top` property: A navigation bar that gets sticky when the user scrolls further down the page:

{% codepen https://codepen.io/patriscus/pen/dyXbpOE %}

As you can see, the navigation bar sticks at the top of the page with (in this case) a zero pixel offset, essentially meaning right at the top of the screen. Feel free to go to the CodePen and play around with the top value. This way, you'll see that the navigation bar will start to stick sooner or later, depending on which value you've entered.

When you compare sticky to fixed, you can clearly see some similarities. When I was beginning to learn about the sticky value, I initially thought of it as "a delayed position fixed". While in some sense that's still how I think about it, an important aspect is that sticky is confined within the nearest scrollable ancestor.

Why would you care? Because that means, __sticky stops being sticky when it reaches the end of the ancestor__. This is a minor detail that initially didn't fit my "delayed fixed position" mindset. And because of that, I tried to come up with a quick visualization on what exactly I mean:

{% codepen https://codepen.io/patriscus/pen/mdEbWqe %}

The sticky element stops right at the bottom of the container it is defined in. This is a really neat way to produce layout & designs that require an element to be sticky while scrolling through the page. I implemented a short prototype to show you a potential use case:

{% codepen https://codepen.io/patriscus/pen/MWyNXwx %}

### Final considerations

![Two man standing in front of a whiteboard, one turning and nodding to the audience - text on screen reads "Think about it"](https://media.giphy.com/media/RrpeMQCWQS3K0/giphy.gif)

`sticky` made it much more convenient for developers to define elements that need to stick at certain regions of the page. While previously you had to rely on JavaScript for that, you can now simply use the built-in CSS properties to accomplish the same effect with much less overhead and implementation effort.

However, checking [caniuse.com](https://caniuse.com/css-sticky) will show you that while the browser support overall is really good, you still have to think about IE11 if you still need to support it. 

I hope this little post was able to help some to hear/learn about position `sticky`. If you have any feedback, tips or just generally want to say hi, please feel free to leave a comment. Alternatively, you can hit me up on [Twitter](https://twitter.com/patriscus) as well.