DEV Community

Rob OLeary
Rob OLeary

Posted on • Updated on • Originally published at roboleary.net

Make it stick! Sticky headers in CSS πŸ¦ŽπŸ”

CSS introduced the property position: sticky in 2012, one obvious application of this is for making sticky headers.

The idea is straightforward: If an element has position: sticky, treat it as a normal position: relative block, as long as it’s on screen. If the user scrolls far enough that the element (let’s say it’s a h1) will move off the screen, but it's parent is still visible onscreen, treat it as though it were position: fixed.

Initially, the problem with this property was that adoption was slow by some browser vendors, but that is no longer an issue, so we can embrace it without big reservations now! There is a caveat with tables, which I will discuss below.

So, how do you make sticky headers with just CSS?

It’s super-easy!

All you do is:

.stayOnTop{
    position: -webkit-sticky;
    position: -moz-sticky;
    position: -ms-sticky;
    position: -o-sticky;
    position: sticky;
    top: 0;
}
Enter fullscreen mode Exit fullscreen mode

The position is set through the properties: top, left, right, bottom. So, to have the element stay on top, use top: 0;.

Using the browser prefixes is still necessary for some Browsers such as Safari, so it's best to add them all, and avoid cross-browser compatibility mishaps!

Tables

One of the best use-cases for this is for bigggg tables. Tables where you want to see the column headers on top as you scroll down through your data.

There is one caveat though, Chrome and Edge have a bug with using position: sticky on thead. So, the way around this is to apply it to th instead.

You can use it to make sticky headers on the side and top for easy cross-referencing for big data sets, maybe you're showing scientific findings like below! So, it kind of mimics frozen rows in Excel!

Other Use Cases

  • It is used often to make a sticky navigation bar when there is a hero section above it. The navigation bar becomes fixed when the user scrolls past the hero section.

  • I think the example below is cool, but it requires some JS. A reading progress bar for a blog post. Scroll to see it in action. You can get creative with sticky too!

I wrote a tutorial on this if you would like to learn more.

Browser Support

As long as you avoid using it on thead, you are good on the major browsers (see green-shaded squares in image below). IE be damned!😜

can i use table

Top comments (14)

Collapse
 
husseinkizz profile image
Hussein Kizz

The reading progress bar is so cool, how can I use it? Please!

Collapse
 
robole profile image
Rob OLeary • Edited

Hi Hussein, The code is available inside the codepen example. You can see the code by clicking on the tabs (HTML, CSS, JS). It requires some JS to work. So just keep this in mind if you want to use it yourself

Collapse
 
husseinkizz profile image
Hussein Kizz

Yeah I saw the resource button after you know am new here! But thanks for sharing and another thing you mean it can't work with just html css and JavaScript only??

Thread Thread
 
robole profile image
Rob OLeary • Edited

No worries Hussein! This example requires JS because the progress bar is updated based on the position of the scrollbar of the window, this is not possible to do in CSS. The other examples use CSS only. I will add this to the post, so it is clear for everyone!

Thread Thread
 
husseinkizz profile image
Hussein Kizz • Edited

K thanks for that great post!! But isn't there any way I can use plain J's without importing the jQuery cause my blog where I wanted to do that it's a bit difficult!

Thread Thread
 
robole profile image
Rob OLeary

Yes. You can make a few changes to the code, so it is plain JS. Then, you do not need to use JQuery.

Thread Thread
 
husseinkizz profile image
Hussein Kizz

Yeah that can work for me, you know am not so fluent with JavaScript so hope you can help me there cause I just want to use that bar on my blog.

Collapse
 
tunetheweb profile image
Barry Pollard • Edited

Safari 13 doesn't require the prefix btw. Though Safari 12 does.

PR for caniuse update: github.com/Fyrd/caniuse/pull/5360

Collapse
 
robole profile image
Rob OLeary

Nice! πŸ’―

Collapse
 
tunetheweb profile image
Barry Pollard

No probs. You also helped me add support for older iOS users for a feature I'm just implementing by reminding me of vendor prefixes for them as some iOS devices stuck with v12 and can't upgrade. So thanks right back at you! πŸ˜€

Collapse
 
ernestsakala profile image
Ernest Sakala

This is nice

Collapse
 
robole profile image
Rob OLeary

thank you πŸ™‚

Collapse
 
abdelrahmanahmed profile image
Wahdan

Support for the new features is faster nowadays, thanks for the article πŸ‘

Collapse
 
robole profile image
Rob OLeary • Edited

Yes, thankfully! Im glad it was helpful :-)