DEV Community

Cover image for Stop Using Fixed Headers and Start Using Sticky Ones

Stop Using Fixed Headers and Start Using Sticky Ones

Luis Augusto on June 25, 2020

Like them or not, headers that stay visible at the top of the page are a very popular UI and will likely not be going away anytime. Many sites make...
Collapse
 
marklchaves profile image
mark l chaves

Hi Luis,

Thanks for the article. Do you have a live code sample? I tried this a few times and I couldn't get it to work for me.

For example, in this pen, I disabled the CSS that compensates for my previous fixed header. Then, I changed my header to position sticky. No luck. All my anchors get hidden under the sticky header.

codepen.io/marklchaves/full/XWXgQJM

I checked to make sure my JS wasn't doing anything funky. I added the plain vanillla HTML anchor also just to make sure it wasn't my JavaScript.

What am I doing wrong?

Thanks!

Collapse
 
luisaugusto profile image
Luis Augusto

Hey Mark, thanks for reading! I took a look at the code and the sticky position does seem to be working, but are you referring to the tabs hiding under the header when you click on the anchor links? That is because anchor links will always bring that particular element to the very top of the page view, so regardless of whether you have a fixed or sticky header, it will always appear underneath when using an anchor link.

To get around anchor links jumping elements to the top of the page, you can add an offset to your #tabstrip element, like so:

#tabstrip {
  margin-top: -100px;
  padding-top: 100px;
}

I hope that helps!

Collapse
 
marklchaves profile image
mark l chaves

Got it. It's also my (mis)understanding of how sticky is supposed to work then. I appreciate that.

BTW, I use this snippet from SE to automatically compensate for fixed headers when using anchors.

:target::before {
    content: "";
    display: block;
    height: 6rem; 
    margin: -6rem 0 0; 
}

Thanks again!

Thread Thread
 
luisaugusto profile image
Luis Augusto

Awesome thanks for that, either way works!

Collapse
 
waylonwalker profile image
Waylon Walker

I've been using headroom for a few months and like the simplicity (on my behalf) that it provides to make the nave hop in and out kinda like a more native mobile app.

showing it in action on waylonwalker.com

Here it is on waylonwalker.com

Collapse
 
luisaugusto profile image
Luis Augusto

Yea I also think this is a great approach, hiding the header when scrolling down and bringing it back when scrolling up. Easy to access and while still preserving screen real estate, and pretty easy to implement!

Collapse
 
iamshareque profile image
Shareque

I recently face this issue for a sidebar header,
the position:sticky act as draggable content on iPad where as position: fixed stick to given position, works normal.

Collapse
 
dorshinar profile image
Dor Shinar

To be honest, I'm not a fan of either. I find it much simpler to use overflow-y: scroll on the element actually being scrolled (in DEV's case the articles), instead of fiddling with header position.

Collapse
 
pavelloz profile image
Paweł Kowalski

TBH on my computer DEV headers are not sticked/fixed/anything else.

Collapse
 
luisaugusto profile image
Luis Augusto

Sorry I didn't realize this when I wrote it, but looks like it's a setting in the UX options:

Collapse
 
pavelloz profile image
Paweł Kowalski

Ouh, that must be it :) I dont like things taking up vertical space so i probably turned it off long time ago and forgot :))

Collapse
 
oskrgg profile image
Oscar González

Does anyone notice the extra space(~1px) above the header when scrolling down. I can see it in Chrome only, other browsers works perfectly.
Any idea how to fix it?
dev-to-uploads.s3.amazonaws.com/up...

Collapse
 
charlznchew profile image
Charlie

A case for sticking with fixed header positioning involves headers that condense vertically when scrolling down the page, then expand again when user scrolls to top again (say, 100px threshold). Since sticky header is within document flow, when that animation occurs, it tweaks the scrollY value. The listener can get stuck performing the condense/expand animation in infinity loop. For example, user scrolls up and scrollY = 95px so the header expands by 10px. ScrollY is now 105px so header collapses and now scrollY = 95px again, and so on. It looks like the frenetic stutter step a squirrel makes when hesitating which way to run out of the road, not pleasant!

Collapse
 
jbmanllr profile image
Jean-Baptiste Manillier • Edited

Hi, i track the container height and use the difference to adjust the minimize offset.

eg in react:

`
const { scrollY } = useScroll();
const previousHeightRef = useRef(0);

const minimizedRef = useRef(minimized);
minimizedRef.current = minimized;

const adjustOffset = (offset: number) => {
const currentHeight = containerRef.current?.offsetHeight || 0;
const heightDifference = previousHeightRef.current - currentHeight;
return Math.max(0, offset - heightDifference);
};

const handleScroll = useMemo(
() =>
throttle((latest: number) => {

      const adjustedMinimizeOffset = adjustOffset(minimizeOffset || 0);
      if (latest > adjustedMinimizeOffset) {
        if (!minimizedRef.current) {
          setMinimized(true);
          minimizedRef.current = true;
        }
      } else {
        if (minimizedRef.current) {
          setMinimized(false);
          minimizedRef.current = false;
        }
      }

    if (containerRef.current) {
      previousHeightRef.current = containerRef.current.offsetHeight;
    }
  }, 300),
[scrollY, flyOutOffset, minimizeOffset],
Enter fullscreen mode Exit fullscreen mode

);

useMotionValueEvent(scrollY, "change", handleScroll);`

Collapse
 
pavelloz profile image
Paweł Kowalski

I decided to write a post that adds on top of yours: dev.to/platformos/scrolling-to-the... :)

Collapse
 
luisaugusto profile image
Luis Augusto

Nice, thanks!

Collapse
 
quodline profile image
Quodline

I prefer to hide the header when the user scrolls down and show it when the user scrolls up even slightly. I think it manages space better for small mobile phones.

Collapse
 
luisaugusto profile image
Luis Augusto

That's also a great option, and I'm done that for a few sites as well. You can also use sticky header in that situation and just animate its position with transform: translateY(-100%)

Collapse
 
detzam profile image
webstuff

Sooo sticky will let it hold the space in the dom, soi i won t need to add a margin top

Collapse
 
luisaugusto profile image
Luis Augusto

Exactly

Collapse
 
henryornellas profile image
henryornellas

Great post! I couldn't believe reading all those extra lengthy css stackOverflow answers/youtube tutorials. Worked great, thanks.

Collapse
 
zulqurnain profile image
🇧🇴°•°• Simon Bolivar •°•°🇧🇴

fkn genius!~
sticky all the way instead of this js gunk
thanks for the post

Collapse
 
philsav2017 profile image
Philip

this is good works perfectly