Sticky

It’s easy to toss position: sticky; top: 0; on something. But for it to work, it’s gotta be within a taller parent element. So, the unordered list (<ul>) within the navigation (<nav>) works great here. Thanks to the CSS grid layout, the <nav> is as tall as the <main> content area. However, note that that we also gotta position: -webkit-sticky; for iOS.

I also tossed in a magic number for the vertical media query so that it doesn’t stick in such a way that you can’t get to the lower navigation items:

Then it occurred to me, CSS can do this! There is a scroll-behavior property and you can put it on the document to make everything scroll that way:

html {
scroll-behavior: smooth;
}

Since our navigational <a> links are hash/jump/anchor links, that’s literally all we need. Forget the JavaScript. Especially because the browser support for scroll-behavior is the same as the “smooth” version of .scrollIntoView().

Active

This is a bit trickier, particularly because this is a single-page scrolling app rather than individual pages with their own separate documents. If they were separate documents, we’d change an active class somewhere in the navigation or use a body.specific_page class or something.

Instead, we’ll need to look at the scroll position of the page, decide which section is in view and mark it that way. There might be some kinda fancy IntersectionObserver way to handle this, but I couldn’t quite wrap my head around that, so instead I’m just looking at all the relevant sections, doing a little measuring and math, and deciding if the link is active that way.

The Plateforme Citoyenne is a not for profit organisation advocating for a clean and sustainable future. Founded in 2012, its main focus has been oriented towards the preservation of the Mauritian Ecosystem. The group also channels its energy towards societal activism, all with the aim to promote and produce sustainable communities.