Persistent Headers

Avatar of Chris Coyier
Chris Coyier on (Updated on )

DigitalOcean provides cloud products for every stage of your journey. Get started with $200 in free credit!

This is some code to get the header of some content area to stay visible at the top of the screen as you scroll through that content. Then go away when you’ve scrolled past that relevant section.

Header… persisting.

Couple things to know before we get started:

  1. There are many like it, but this one is mine.
  2. This doesn’t work (yet) on mobile (at least mobile Safari that I looked at). Because I don’t know that much about JavaScript on mobile and how to detect scroll events and scroll position and stuff.


For the sake of demo purposes, we’ll identify areas we wish to apply persistent headers to via a class name “persist-area” and the header within we indent to be persistent with “persist-header”. These are totally unsemantic class names, but you’d fix that in your own implementation by just knowing your own markup and applying appropriate selectors.

<article class="persist-area">
   <h1 class="persist-header">
   <!-- stuff and stuff -->

jQuery JavaScript

This is the plain English of what we are going to do:

  1. Loop through each persistent area and clone the header. The cloned header remains invisible until we need it.
  2. Every time the window scrolls, we run some tests.
  3. If we have scrolled into an area which should have a persistent header, but the header would be hidden, we reveal our cloned header, in a fixed position. All other persistent headers will be hidden.

The whole kit and kaboodle:

function UpdateTableHeaders() {
   $(".persist-area").each(function() {
       var el             = $(this),
           offset         = el.offset(),
           scrollTop      = $(window).scrollTop(),
           floatingHeader = $(".floatingHeader", this)
       if ((scrollTop > && (scrollTop < + el.height())) {
            "visibility": "visible"
       } else {
            "visibility": "hidden"

// DOM Ready      
$(function() {

   var clonedHeaderRow;

   $(".persist-area").each(function() {
       clonedHeaderRow = $(".persist-header", this);
         .css("width", clonedHeaderRow.width())


The only CSS we’re directly changing with JavaScript is the visibility of the persistent header. I feel like that’s pretty acceptable. All other styling is rightfully a part of the class. It’s pretty light, all we need is:

.floatingHeader {
  position: fixed;
  top: 0;
  visibility: hidden;

And so…

Use as you will.

View Demo   Download Files