Sticky Header

This commit is contained in:
2026-06-16 14:00:32 +02:00
parent f8b09e18bd
commit 7fe0013a5c
+28 -4
View File
@@ -36,8 +36,18 @@
--font-xs: 0.75rem;
--font-sm: 0.85rem;
/* Height of the sticky top header. Single source of truth for the
sidebar/TOC top offsets and anchor scroll-padding. Hardcoded (the
desktop header is a single-row grid); revisit if the header wraps. */
--header-h: 3.25rem;
}
/* Anchor / TOC jumps land below the sticky header instead of behind it.
Harmless on mobile view mode (header not sticky there) — adds only a
small gap above the target. */
html { scroll-padding-top: var(--header-h); }
/* === Base === */
body {
background: var(--bg);
@@ -95,6 +105,10 @@ main { padding: var(--space-5) var(--space-4); width: 100%; flex: 1; min-width:
centre stays reserved even when search is hidden in editor mode. Mobile
(≤1100px) collapses to a two-row layout — see responsive block below. */
header {
position: sticky;
top: 0;
z-index: 40;
background: var(--bg);
padding: var(--space-3) var(--space-4);
border-bottom: var(--border-dashed);
display: grid;
@@ -487,13 +501,18 @@ button.fab { display: none; }
/* === Sidebar === */
.sidebar {
position: sticky;
top: var(--space-4);
/* Park below the sticky header. The space-2 buffer also absorbs the small
difference between --header-h and the real rendered header height, so the
sidebar is already at its pinned offset at scroll 0 — no pre-pin travel.
Do NOT add margin-top: a top margin sits above the pin point and makes
the sidebar visibly jump up by that margin when scrolling starts. */
top: calc(var(--header-h) + var(--space-2));
align-self: start;
max-height: calc(100vh - 2rem);
max-height: calc(100vh - var(--header-h) - var(--space-4));
display: flex;
flex-direction: column;
gap: var(--space-4);
margin-top: var(--space-5);
padding-top: 1rem;
}
aside.sidebar:empty { display: none; }
@@ -507,7 +526,7 @@ aside.sidebar:empty { display: none; }
static via the .panel-sidebar density class. */
.toc {
position: fixed;
top: var(--space-4);
top: calc(var(--header-h) + var(--space-2));
right: var(--space-4);
width: 14rem;
max-height: calc(100vh - 6rem);
@@ -679,6 +698,11 @@ aside.sidebar:empty { display: none; }
/* Single-row mobile header: logo + Up icon are compact so search can
take the middle flex column, with actions on the right. */
header { grid-template-columns: auto 1fr auto; }
/* Mobile view mode: header scrolls away with the page (out of scope to
stick it). It re-sticks only in edit mode so SAVE/CANCEL stay reachable
on long documents. */
header { position: static; }
body.edit-mode header { position: sticky; top: 0; }
.search-form { width: 100%; max-width: none; justify-self: stretch; }
/* Sidebar on mobile is a floating overlay toggled by the FAB. The aside
itself is the scroll container; children render at natural height. */