CSS Sticky Positioning (All You Need to Know)

Learn about the basic of Sticky position and some advanced tips like adding a class when the element becomes sticky.

Sticky positioning is my favorite addition to CSS in recent years. It allows an element to behave like fixed position when you scroll past it.

In this article, we will learn the basics and some advanced tips like adding a class when the element becomes sticky.

1. How to Make Sticky Element

.sticky-nav {
  position: sticky;
  top: 0;
}

There are 3 rules you need to follow to make it work:

  1. It sticks to the direct parent. It can’t go beyond that.
  2. The HTML markup must be placed correctly. If you want it to stick to the bottom, then you need to place it at the bottom.
  3. You need to use the correct direction property like top if you want it to stick at the top.

LIVE EXAMPLE:

As you can see, the sticky bar only sticks up to the parent’s height.

2. On Sticky Listener

There is no native way to check if the element is currently sticky or not.

So we must fall back into using JavaScript to check the position of sticky elements every time we scroll.

(function() { 'use strict';

var target = '.sticky-bar';
var classToToggle = '--stuck';
             
document.addEventListener( 'DOMContentLoaded', onReady );

function onReady() {
  // if doesn't support Sticky
  if( !( CSS.supports && CSS.supports( 'position', 'sticky' ) ) ) { return; }
  
  // Get the sticky elements and convert it into array
  var $elems = [].slice.call( document.querySelectorAll( target ) );
  
  // Initial check if already sticky
  $elems.forEach( checkStickyState );
  
  // Add scroll listener to check each elements
  window.addEventListener( 'scroll', (e) => {
    $elems.forEach( checkStickyState );
  } );
}

function checkStickyState( $elem ) {
  var currentOffset = $elem.getBoundingClientRect().top;
  var stickyOffset = parseInt( getComputedStyle( $elem ).top.replace( 'px','' ) );
  var isStuck = currentOffset <= stickyOffset;

  if( isStuck ) {
    $elem.classList.add( classToToggle );
  } else {
    $elem.classList.remove( classToToggle );
  }
}
             
})();

LIVE EXAMPLE:


Conclusion & Browser Support

From the CanIUse chart, we can tell that the support is excellent as long as you’re not using it on Table. IE doesn’t support it but that’s okay since your site still looks fine without the sticky element.

For browser prefix, you still need to add -webkit- for Safari:

position: -webkit-sticky;
position: sticky;

As always, feel free to ask question in the comment below 🙂

Default image
Henner Setyono
A web developer who mainly build custom theme for WordPress since 2013. Young enough to never had to deal with using Table as layout.