Skip to content

Instantly share code, notes, and snippets.

@bartwttewaall
Last active January 16, 2024 09:03
Show Gist options
  • Save bartwttewaall/19530622761255d65a5bc4d66a33baaa to your computer and use it in GitHub Desktop.
Save bartwttewaall/19530622761255d65a5bc4d66a33baaa to your computer and use it in GitHub Desktop.
export function initNavigation() {
const navigation = document.querySelector<HTMLElement>("[data-navigation]");
if (navigation) initSticky(navigation);
}
function initStickyBehaviour(root: HTMLElement) {
// hide the top navigation on scroll
const topNav = root.querySelector<HTMLElement>("[data-topnav]");
if (!topNav) {
// No topNav? Then always be sticky.
root.classList.add("is-sticky");
root.style.top = "0px";
return;
}
// evaluate if the topnav is visible and if its height needs to be taken into account
const evaluate = () => {
const isSticky = root.classList.contains("is-sticky");
const isMobile = root.classList.contains("is-mobile");
topNav.style.display = isMobile ? "none" : "flex";
root.style.top =
isSticky || !isMobile ? `-${getFullHeight(topNav)}px` : "0px";
};
// observe the intersection of topNav
const io = new IntersectionObserver(
(payload: IntersectionObserverEntry[]) => {
const { isIntersecting } = payload[0];
root.classList.toggle("is-sticky", !isIntersecting);
evaluate();
}
);
io.observe(topNav);
// observe the body width
const ro = new ResizeObserver((entries: ResizeObserverEntry[]) => {
const width =
entries[0].borderBoxSize?.[0].inlineSize || document.body.clientWidth;
root.classList.toggle("is-mobile", width < 768);
evaluate();
});
ro.observe(document.body, { box: "border-box" });
}
const heightProperties = [
"height",
"margin-top",
"margin-bottom",
"border-top-width",
"border-bottom-width",
];
function getFullHeight(el: HTMLElement) {
const currentStyle = window.getComputedStyle(el);
return heightProperties.reduce(
(value, key) => value + parseInt(currentStyle.getPropertyValue(key)),
0
);
}
[data-navigation] {
&.is-sticky {
postition: sticky;
top: 0;
z-index: 9999;
}
}
<section data-navigation>
<nav class="flex flex-row justify-between items-center px-10 py-2 border-b text-sm" data-topnav>
<div class="flex gap-x-6">
<a href="mailto:info@...com" rel="nofollow"><i class="bx bxs-envelope mr-1"></i>info@...com</a>
<a href="tel:0000000000" rel="nofollow"><i class="bx bxs-phone mr-1"></i>000 - 0000 000</a>
</div>
<div class="flex gap-x-6">
<a href="#">Login</a>
<a href="#">Register</a>
<a href="#">Contact</a>
</div>
</nav>
<nav class="flex flex-row justify-between items-center px-10 py-3" data-mainnav>
<a href="/" class="brand">Logo</a>
<ul class="navigation" data-links>...</ul>
</nav>
</section>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment