DEV Community

loading...
Cover image for Why it's time to embrace position sticky

Why it's time to embrace position sticky

mattstuddert profile image Matt Studdert ・2 min read

Whenever I've taught people about CSS position, I've always warned against using position: sticky;.

Browser support for all position values has been great, except for sticky. So, what's the point in using something that's not going to work a lot of the time?

But, I must say, I've now changed my tune! During the build of Frontend Mentor, I was looking for a simple solution to create a sticky menu on the resources page. The menu allows you to jump between categories on the page and is not part of the main header. All it needed to do was stick to the top of the viewport when the element was scrolled to and leave when the container was scrolled past.

Sure, it would be very easy to install an npm package to achieve that effect, but I wanted to use the simplest approach possible.

As I knew this was the exact behaviour offered by position: sticky; I thought I'd have a look at current browser support:

caniuse.com browser compatibility stats with CSS position sticky, showing over 86% global browser compatibility

Not too bad! Over 86% of browsers used around the world support position: sticky; and pretty much all major modern browsers support it.

But what happens if someone comes to the site on a browser that doesn't support it? Simple! The element just doesn't stick to the viewport. No mass chaos or breaking of the internet. Just no sticky element.

The site's main users are web developers (both current and aspiring). So it was entirely reasonable to assume the vast majority of people accessing the site will do so through a modern browser.

I went ahead and used it, and I must say it put a smile on my face 🙂 Here's the menu bar sticking to the top of the viewport as you scroll down the page:

Animated GIF of CSS position sticky property sticking navigational menu to the top of the screen

And here it is un-sticking itself as you scroll past the parent element:

Animated GIF of CSS position sticky property releasing navigational menu from the top of the screen when the user scrolls passed the container

Easy!

If you'd like to check it out properly, head over to the resources page on the site.

Want to have a sticky sidebar on your blog post page? The basic markup could be as follows:

<!-- parent element -->
<section> 
    <article>
        ...
    </article>

    <!-- sticky element -->
    <aside>
        ...
    </aside>
</section>

As soon as the section element moves out of the viewport the aside will un-stick itself and move off-screen.

So, next time you're in need of a sticky sidebar or a menu, like me, consider using position: sticky;.

Keep in touch

If you'd like to stay in touch you can follow Frontend Mentor or follow my personal account on Twitter. Feel free to say hi! 🙂

Discussion (19)

pic
Editor guide
Collapse
juanmanuelramallo profile image
Juan Manuel Ramallo

Would be nice to have this in the article actions/reactions bar, to stick it at the bottom of the article card/container.

Collapse
ben profile image
Ben Halpern

I didn't even know about position: sticky, I'd only seen this done via JS which I never really liked. This is definitely something I could see us making use of.

Collapse
link2twenty profile image
Andrew Bone

There was a little talking about when the reaction bar changed.

dev.to/entrptaher/comment/5fdn

Collapse
mattstuddert profile image
Matt Studdert Author

Yeah, it’s great! Makes sticky elements super easy to implement.

Thread Thread
ben profile image
Ben Halpern

I imagine this is much more performant than JS-driven alternatives?

Thread Thread
mattstuddert profile image
Matt Studdert Author

I couldn’t say for sure, as I haven’t looked into the performance side. But I’d imagine so without any listeners.

Thread Thread
ben profile image
Ben Halpern

I already quickly implemented this in an internal tool for dev.to

PR: github.com/thepracticaldev/dev.to/... 😄

Thread Thread
equinusocio profile image
Collapse
peksipatongeis profile image
peksipatongeis • Edited

I suggest to use this with a feature query, @supports (position: sticky). With feature query if you want to offset the sticky point, like top: 20px, it will only apply the top value to the element if position: sticky is supported.

Collapse
rdumais profile image
Ryan

I am a fan of 'position: sticky'. You have shown how it works great for webpage's headers, but think about how we can use it to improve other UIs.
Sticky headers work great for long tables/lists of information where the column header needs to be referenced continuously.

Collapse
mattstuddert profile image
Matt Studdert Author

For sure! There’s plenty of opportunities to improve UIs. Will be thinking how else I could use it. The only problem will be trying to not get too carried away 😂

Collapse
chemicalkosek profile image
Kosek • Edited

Except it doesn't work well in table headers. I mean check this example:
charliepark.org/css-only-sticky-he...

It works for me only in Firefox Mobile. Not in desktop Chrome or Firefox.

Does it work for anybody?

Collapse
link2twenty profile image
Andrew Bone • Edited

It seems to work ok for me.

EDIT:

Just looked at the page you linked their elements table is wrong, they need to put sticky on the th not the thead.

Adding this CSS would fix their problem.

#example_sticky_header_container thead th  {
  position: sticky;
  top: 0;
}
Collapse
jkane50 profile image
jkane50 • Edited

The above css could cause a problem if there was more than one header row. Since top:0 is there it should only be applied to the 1st header row.
thead tr:first-child th {
position: -webkit-sticky;
position: sticky;
top: 0;
background-color: #2eA0ff;

}
Also need webkit for safari.
For multiple header rows you need nth child css or a little javascript where you sum the height of the previous rows.

Collapse
jkane50 profile image
jkane50

Used position sticky recently to fix the header row in a table. It worked but when I was done I really didn't understand why I couldn't put position:sticky on the

after the rather than on individual tags. Also, I had a backgroundColor set on the TR parent of TH but after applying position:sticky to the child
tags, I had to put the backgroundColor directly on the
tags. I don't understand either of these things which means I don't fully understand position sticky. can you explain?


Collapse
link2twenty profile image
Andrew Bone

I love that you can easily give tables sticky headers with no extra work.

Collapse
equinusocio profile image
Mattia Astorino

It miss only one think... an event. But there’s a workaround.

developers.google.com/web/updates/...

Collapse
juanmanuelramallo profile image
Collapse
kurtainz profile image
Kurt Corbett

Cool! I had not heard of this one at all.