4. Scroll Behavior and Route Transitions
Keeping the site navigation visible at all times reduces the space available for content in long weekly articles. Real Terms therefore hides the site navigation while the user scrolls down and displays it again while the user scrolls up or approaches the top of the page. This behavior is shared with Significant Bit, which is built with VitePress.
Classes That Represent Visibility
CSS controls the visible position. .eg-site-nav uses position: fixed and applies a 0.3-second transition to changes in transform.
.eg-site-nav.scrolled-down {
transform: translateY(-100%);
pointer-events: none;
}
.eg-site-nav.scrolled-up,
.eg-site-nav.is-open {
transform: translateY(0);
}.scrolled-down moves the site navigation upward, and pointer-events: none prevents the hidden element from receiving pointer input. While the menu is open, .is-open applies translateY(0), preventing the header from moving out of the viewport while the full-screen panel remains visible.
The transition is disabled when the user has selected prefers-reduced-motion: reduce.
setupSiteNavScrollReveal
The setupSiteNavScrollReveal() function in app.js determines the scroll direction. It is called once from the ready hook in siteChrome.
function sync() {
var nav = document.querySelector(".eg-site-nav");
if (!nav) {
return;
}
var y = window.scrollY;
if (nav.classList.contains("is-open") || y <= nearTopPx(nav)) {
nav.classList.remove("scrolled-down");
nav.classList.add("scrolled-up");
lastY = y;
return;
}
if (y > lastY) {
nav.classList.add("scrolled-down");
nav.classList.remove("scrolled-up");
} else if (y < lastY) {
nav.classList.remove("scrolled-down");
nav.classList.add("scrolled-up");
}
lastY = y;
}The conditions are as follows.
- Near the top
nearTopPx()returnsmax(8, nav.offsetHeight). When the navigation is 64px high, it remains visible within approximately 64px of the top of the page. - Scrolling down
If the current positionyis greater than the previous positionlastY, the function adds.scrolled-down. - Scrolling up
Ifyis less thanlastY, the function adds.scrolled-up. If the position has not changed, it retains the current visibility state. - Menu open
If.is-openis present, the navigation remains visible regardless of the scroll position. When opening the menu,setSiteNavOpen()also removes.scrolled-downand adds.scrolled-up.
The scroll event listener uses { passive: true } to indicate to the browser that the handler does not prevent scrolling.
Restoring Visibility After Route Transitions
Docsify uses a hash router. Opening an article changes the URL hash to a value such as #/2026/weekly/CW36.md. Although $docsify.auto2top is enabled, the site navigation must also reset its own state to guarantee the intended presentation after a route transition. Combined with the tabindex insertion described in Chapter 2, this prevents navigation to the home page from hiding the site navigation when Docsify scrolls to the first heading.
The following processing runs whenever the route changes.
function pinTop() {
revealNav();
if (isHome() && !hasHeadingTarget() && window.scrollY !== 0) {
window.scrollTo(0, 0);
}
lastY = window.scrollY;
sync();
}
function syncAfterRoute() {
pinTop();
routeTimers.forEach(clearTimeout);
routeTimers = [setTimeout(pinTop, 50)];
}syncAfterRoute() is called at the following two points.
hashchange
Called when the browser hash changes.- The
doneEachhook insiteChrome
Called when Docsify finishes rendering the content for each route. Because the scroll position can change after rendering,pinTop()also runs 50ms later.
isHome() uses currentReportPath() to determine whether the current hash identifies an article. It calls scrollTo(0, 0) only when the route is the home page, no ?id= heading target is present, and the current position is not already at the top. If a heading anchor is present, navigation to that heading takes priority.
Separating Hash Routes from Regular URLs
Site navigation links use regular paths and do not preserve the Docsify hash. Selecting Home, Significant Bit, or About navigates away from the Real Terms single-page application.
The sidebar and links in article content handle navigation within Real Terms. These links use #/… hash routes. The site navigation identifies the current site, while the sidebar identifies the current article within that site. Not using the official Navbar preserves a clear distinction between navigation across sites and navigation within the documentation.