Skip to content

Fix the header on scroll, in print and on AI pages - #248

Merged
mlaetitia merged 8 commits into
mainfrom
fix/T51ENG-2081-header-shrink
Oct 30, 2026
Merged

mlaetitia merged 8 commits into
mainfrom
fix/T51ENG-2081-header-shrink

Conversation

@mlaetitia

Copy link
Copy Markdown
Collaborator

Related to T51ENG-2081

Proposed changes

  • Header: smaller on scroll above 1200px, with no flicker, and a white background across the full width.
  • Below 785px: the logo shrinks on the way down and returns on an upward scroll. The header stays 125px tall.
  • Print: the logo prints once, and the menu and header buttons no longer print over the text.
  • AI header pages: content starts below the header, and the green trim stays 10px when a menu opens.

Why are these changes being made?

These fixes were tested on develop and approved for production on T51ENG-2081.

Testing instructions

  • Above 1200px: scroll down and the header shrinks, with no flicker or menu reflow.
  • At phone width: scroll down and the logo shrinks, then scroll up about 100px and it returns.
  • Hover a menu item: the white background spans the full page width.
  • Print preview a long page: the logo appears on page 1 only, with no menu or buttons.

🤖 Generated with Claude Code

mlaetitia and others added 8 commits October 28, 2026 18:59
The header shrank only after 100px of scrolling, and a single threshold meant
the 25px the page lifts on shrinking could be handed back by scroll anchoring,
re-crossing the bound and toggling the class repeatedly. The threshold to beat
now depends on which state the header is in, so no correction can reach the
other bound, and the handler runs once per animation frame on a passive
listener. Mobile and desktop share one path; the mobile header no longer grows
back mid-page on an upward scroll.

max-height had no length to animate from, so the shrink snapped rather than
eased; the base rules now set one, and the transitions name the properties that
actually change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011rCHPCdbV5C5dDJjEmMDuy
(cherry picked from commit a3ef8d6)
…e page

The header is sticky but sits in flow, so shrinking it moved everything below it
and left the nav drifting up on a small scroll. It now holds its height and only
the logo shrinks, which also removes the content shift that made the class
toggle in a loop, so the scroll handler needs a single threshold again.

The white background moved off the header box onto a veil that escapes the
wrapper's 5vw inset, so it reaches both edges of the page as the design asks.
The megamenu panel already did this; both now share one mixin, and the AI
template's green trim rides along with it.

Along the way: the row is centred again now that nothing overrides the
unbalanced top padding, dropdowns are no longer clipped while scrolled, and the
1200px breakpoint no longer falls in both branches at once.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011rCHPCdbV5C5dDJjEmMDuy
(cherry picked from commit 68bb1b1)
Three things still shifted when the header went small. The logo column took its
width from the logo, so shrinking the logo handed the nav that width and the
menu reflowed from two rows to one. The admin bar offset applied only to the
small state, so logged-in users saw the whole header drop 32px the moment the
class flipped. And the menu links were re-padded, left over from when the header
itself got shorter.

The column now holds its width, the offset applies in both states, and the link
padding is gone. Only the logo changes, which is the point.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011rCHPCdbV5C5dDJjEmMDuy
(cherry picked from commit 3c36769)
The header shrank on scroll until #241 removed it. Shrinking a `position:
sticky` header reflows the page, Chrome corrects scrollY to hold its scroll
anchor still, and that correction re-crosses the shrink threshold in a loop.
That was the flicker, and it was Chrome-only because Safari has no scroll
anchoring.

Fixing the header to the viewport and leaving a constant-height spacer in its
place means the shrink costs the document nothing, so nothing corrects and
nothing loops. The header then spans the viewport, so it carries the wrapper's
inset itself and the megamenu panel no longer needs to escape one.

125px to 90px is as far as the bar can go: the logo column is pinned at 300px
so the menu never reflows, which leaves the menu two rows below roughly
1690px, and two rows need 88px once `$navPadSmall` tightens the nav.

Desktop only. Below `$break-nav` the off-canvas menu measures itself against
`$headerInnerHeight`, so the mobile header keeps its height and only the logo
shrinks, exactly as before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011rCHPCdbV5C5dDJjEmMDuy
(cherry picked from commit 7c137e7)
Compiled CSS is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011rCHPCdbV5C5dDJjEmMDuy
(cherry picked from commit df39967)
#240 merged the mobile and desktop scroll paths into one absolute threshold,
which dropped the behaviour production has below 785px: the full-size logo
returns on any upward scroll rather than only at the top of the page. The
partner asked for production's behaviour to be kept.

Three cases could leave the logo stuck small. The handler runs once per
animation frame, so a single frame can swallow a whole flick, and recording the
turning point where the frame landed rather than at the peak it turned from made
the restore unreachable after a back-to-top jump, a hard flick up from just
below the fold, or iOS overscroll reporting a negative position. It now records
the peak, clamps the position at zero, and clears the peak on the wide path so a
rotation cannot carry a stale one.

matchMedia replaces the innerWidth read, so crossing 784px re-decides instead of
waiting for the next scroll event.

No CSS changed. The bar keeps its height at every width, so the logo row and the
menu button stay where they are.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011rCHPCdbV5C5dDJjEmMDuy
(cherry picked from commit 507aa45)
…AI pages, and keep the AI trim single when a menu opens

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on the page text

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mlaetitia
mlaetitia merged commit 516c4e9 into main Oct 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant