diff --git a/css/styles.css b/css/styles.css
index 2da5b98..d57be8e 100644
--- a/css/styles.css
+++ b/css/styles.css
@@ -199,6 +199,9 @@ table {
--color-push-box-bg: #EBEEF4;
+ /* Layout */
+ --site-header-height: 210px;
+
--color-success: #22c55e;
--color-error: #ef4444;
--color-warning: #f59e0b;
@@ -317,10 +320,16 @@ 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;
+ padding-top: 16px;
+}
+
@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..61931b5 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 220ms ease;
+ }
+
+ ::slotted(top-bar) {
+ position: relative;
+ z-index: 2;
border-bottom: 1px solid var(--color-border, #e2e8f0);
}
`;
}