If you’re working in a component-driven framework like Angular, you might notice one day that your components start ignoring your router’s scroll events and are no longer sticky. All of a sudden, you find the only way to keep your components from scrolling off the page is by assigning them a fixed position with CSS. The only reason this works is because the closest positioned ancestor your components can find is the last possible resort, Document, which represents the whole DOM.
What do you mean by ‘sticky’?
Just to be clear, I’m referring to the CSS property ‘position’ that has the following possible values:
- static – no special positioning
- relative – normal positioning
- fixed – always in the same place, regardless of scroll
- absolute – always in the same place relative to its closest ancestor that has positioning
- sticky – always in the same place after it reaches a top, right, bottom, or left scroll position
Using sticky is like fixed + relative.
Fixed is cool if you only care about positioning in respect to the viewport. But using it means your components no longer take space in the DOM, and therefore no longer have any relation to the positioning of everything else in the DOM. This runs the risks for things like overlapping, cropped and/or empty content.
What kinds of issues are we talking about?
- Applying sticky has no effect on component. It scrolls out of viewport with everything else.
- Applying sticky has partial effect on component. It stays in the right spot until you scroll past the entire length of the screen.
Steps to troubleshoot
Make sure you’ve specified at least a top, left, right or bottom position on the component you’re trying to make sticky.
You can used fixed or relative units, but you must specify at least a top, left, right or bottom position or else it won’t know where to stick.
Make sure your component’s container has a defined height or width.
Your component needs to know the dimensions of its container in order to calculate where the sticking point is in relation to itself. It will continue checking its ancestors until it finds one with positioning.
Make sure your component’s container does NOT have overflow set to hidden.
Once you’ve scrolled your component out of the viewport, it is considered overflow. Therefore, hiding the overflow on a sticky element that needs overflow to stick won’t work.
But what if the height is dynamic?
Let’s say you want the footer to always start at the bottom of the page, even if there’s not enough content to push it down. If you set the component’s container height to 100% and it doesn’t stretch to the end of the page, you might try 100vh. While that works and your component might be sticky at first, you may notice it stops sticking after you’ve scrolled past the full length of the page.
To solve this problem, set the following styles on your component’s container:
.container {
...
min-height: 100vh;
height: 100%;
}