From 80673fd810dba07220097b4a2287471b3946c210 Mon Sep 17 00:00:00 2001 From: rubberducky Date: Thu, 15 Jan 2026 09:44:02 +0000 Subject: [PATCH] feature/small-site-header-on-scroll (#2) Co-authored-by: Tim Rijkse Reviewed-on: https://git.apps.rubberducky.studio/rubberducky/milinda-pitch/pulls/2 --- css/styles.css | 10 +++- index.html | 6 +-- js/components/horizontal-scroll-nav.js | 1 + js/components/site-header.js | 64 +++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 6 deletions(-) diff --git a/css/styles.css b/css/styles.css index 2da5b98..e62780b 100644 --- a/css/styles.css +++ b/css/styles.css @@ -197,7 +197,10 @@ table { --color-border: #e2e8f0; --color-border-light: #f1f5f9; - --color-push-box-bg: #EBEEF4; + --color-push-box-bg: #ebeef4; + + /* Layout */ + --site-header-height: 210px; --color-success: #22c55e; --color-error: #ef4444; @@ -317,10 +320,15 @@ top-bar .actions { width: 100%; min-height: 100vh; margin: 0 auto; + padding-top: 0; background-color: var(--color-background); position: relative; } +site-content { + display: block; +} + @media (min-width: 431px) { body { display: flex; diff --git a/index.html b/index.html index 159b721..148e231 100644 --- a/index.html +++ b/index.html @@ -20,7 +20,7 @@
- +
- - + + diff --git a/js/components/horizontal-scroll-nav.js b/js/components/horizontal-scroll-nav.js index 4b0c2fd..2174481 100644 --- a/js/components/horizontal-scroll-nav.js +++ b/js/components/horizontal-scroll-nav.js @@ -66,6 +66,7 @@ class HorizontalScrollNav extends HTMLElement { scrollbar-width: none; -ms-overflow-style: none; padding: 0 16px; + background-color: #ffffff; } .nav-container::-webkit-scrollbar { diff --git a/js/components/site-header.js b/js/components/site-header.js index e32b45c..8e914a1 100644 --- a/js/components/site-header.js +++ b/js/components/site-header.js @@ -1,15 +1,52 @@ /** * Site Header Component * Sticky header container that holds top-bar, navigation, and search + * Collapses on scroll down, expands on scroll up + * Based on: https://stackoverflow.com/questions/63902512/ */ class SiteHeader extends HTMLElement { constructor() { super(); this.attachShadow({ mode: "open" }); + this.prevScrollPos = 0; + this.headerOffset = 0; + this.collapsibleHeight = 0; + this.handleScroll = this.handleScroll.bind(this); } connectedCallback() { this.render(); + this.collapsible = this.shadowRoot.querySelector(".collapsible"); + window.addEventListener("scroll", this.handleScroll, { passive: true }); + } + + disconnectedCallback() { + window.removeEventListener("scroll", this.handleScroll); + } + + handleScroll() { + const currentScrollPos = window.scrollY; + const isScrollingDown = currentScrollPos > this.prevScrollPos; + const delta = currentScrollPos - this.prevScrollPos; + + if (!this.collapsibleHeight && this.collapsible) { + this.collapsibleHeight = this.collapsible.scrollHeight; + } + + if (isScrollingDown) { + this.headerOffset = Math.min( + this.collapsibleHeight, + Math.max(0, this.headerOffset + delta) + ); + this.classList.remove("reveal"); + } else if (delta < 0) { + this.headerOffset = 0; + this.classList.add("reveal"); + } + + this.collapsible.style.transform = `translateY(-${this.headerOffset}px)`; + + this.prevScrollPos = currentScrollPos; } render() { @@ -20,17 +57,40 @@ class SiteHeader extends HTMLElement { position: sticky; top: 0; z-index: 100; - background-color: var(--color-background, #ffffff); + background-color: transparent; } .header { display: flex; flex-direction: column; + overflow: hidden; + } + + .collapsible { + position: relative; + z-index: 1; + overflow: hidden; + transform: translateY(0); + transition: none; + will-change: transform; + } + + :host(.reveal) .collapsible { + transition: transform 400ms ease; + } + + ::slotted(top-bar) { + position: relative; + z-index: 2; border-bottom: 1px solid var(--color-border, #e2e8f0); }
- + +
+ + +
`; }