Layout Beginner

Sticky headers without JavaScript scroll listeners

The old way used JavaScript scroll events and getBoundingClientRect to toggle a class. Sticky positioning does it in one property.

Old 15+ lines
1// JavaScript: scroll listener
2window.addEventListener('scroll', () => {
3  const rect = header.getBoundingClientRect();
4  if (rect.top <= 0) header.classList.add('fixed');
5  else header.classList.remove('fixed');
6});
7
8.header.fixed {
9  position: fixed;
10  top: 0;
11}
Modern
3 lines
1.header {
2  position: sticky;
3  top: 0;
4}

No JavaScript

The browser handles scroll. No listeners, no getBoundingClientRect, no class toggles.

Respects flow

Sticky stays in layout until it hits the threshold, then sticks. No layout jumps.

One property

Set position and top. Works for headers, sidebars, or any element you want to pin.

Browser Support
97%
Chrome Firefox Safari Edge
Lines Saved
15+ → 3
No JS needed
Old Approach
Scroll listener + class
JS + getBoundingClientRect
Modern Approach
One property
position: sticky

How it works

The old way meant a scroll listener, reading getBoundingClientRect on every scroll, and toggling a class to switch between normal and fixed. That's JS, reflows, and extra CSS for the fixed state.

With position: sticky and top: 0, the header stays in flow until it would scroll past the top, then it sticks. The browser does the work. No script, no class, no layout hacks.

ESC