website/js/teleport.js
the website's source · 310 lines · read it on GitHub
WHAT IT DOES
Following a link to a section of the page lands on that section's heading, with the heading visible.
# The defect this replaces
The header is position: sticky, so the top of the viewport is covered by it. scroll-margin-top is the property for that, and this site set it to a flat 90px. The header is not 90px tall. Measured in a browser it is 133px at desktop widths, 171px where the navigation wraps to three rows, 115px on a phone, 143px at 320px, and 81px on the reference pages. Every one of those is a landing that is wrong, and at the common desktop width it is 43px wrong in the direction that hides the heading behind the header.
It was also set on section, h2 and h3 only, so an h4 or a list item with an id -- which is most of the releases page and every roadmap entry -- had no offset at all and landed a full header height underneath it.
The edition of this site that runs no scripts has never had this problem, because it has no sticky header. That is the standard being matched here.
# How the offset is decided
By measuring the header, not by writing a number down. --anchor-offset is set from the header's own height and kept current by a ResizeObserver, so a header that grows a row, a font that loads late and a phone that is turned sideways all correct themselves. The stylesheet carries a starting value for the moment before this runs, and that value is never the one that matters.
# Why the scroll is repeated
A fragment jump happens once, at the moment the browser reads the hash, and the page is not finished at that moment. An image without intrinsic size finishes loading, a web font replaces the fallback, a reveal transition takes its transform off, and the heading that was in the right place is now somewhere else. So the position is checked over the second that follows and corrected if it drifts, and the checking stops the instant the reader scrolls: catching up with a moving page is the job, fighting the reader is not.
Reveal transitions are settled up front rather than corrected afterwards. .reveal holds an element 18px below where it belongs, and an element scrolled to is an element that has been reached, so the target and anything holding it are shown before the browser scrolls, while the click is still being handled.
# What is deliberately left alone
The navigation itself. Clicks are not prevented and no history entry is written here, because the full-size screenshot viewers are opened by :target, which follows a real fragment navigation and not a pushState. The back button, the middle button and copying a link therefore behave exactly as they do with this file absent, which is also what happens if it fails to load: the stylesheet still clears the header, just less exactly.
IN PLAIN WORDS
Clicking a link that points further down the same page takes you to exactly that spot, with the heading you asked for on screen rather than hidden under the bar at the top, and a brief highlight so you can see where you landed.
WHAT CALLS WHAT
Read out of the source: an edge means the callee’s name appears, called, inside the caller’s body. A syntactic reading, not a resolved one.
| Function | Line |
|---|---|
header | 84 |
measure | 89 |
restingPlace | 100 |
snapTo | 118 |
settleReveal | 131 |
cueFor | 143 |
highlight | 152 |
settle | 179 |
stopSettling | 195 |
teleport | 202 |
named | 243 |
fromHash | 255 |