Skip to content
DocPensieve
0.1.5

ScrollToTop

A link to the top fragment, which the HTML specification reserves for the top of the document when no element carries that identifier. Nothing to add to the template, nothing to load.

It is already there

The button is set on every page, by the shell. Back-to-top is page furniture, not content: writing it in every file would mean repeating it everywhere, and forgetting it somewhere.

Look at the bottom right of this page while scrolling: it is there without anything having asked for it.

To remove it from the whole site:

// docpensieve.config.mjs
scrollToTop: false,

The component, for special cases

ScrollToTop stays available when you want a button in the flow of the text, with its own content — a pointer at the end of a chapter, for instance.

<ScrollToTop className="!static !inline-flex !w-auto" label="Top of page">
  Top
</ScrollToTop>

All three carry !static: that is what takes them out of the corner of the screen to set them in the text. Without this class, they would stack on top of the shell's button, all in the same place.

The accessible name stays set by label: without it, the link would announce itself by its appearance alone.

Appearing

It is driven by animation-timeline: scroll(): scrolling drives the animation, with no event listener. Where the browser does not know that property yet, the button simply stays visible — always there is better than never there.

Smooth scrolling follows the same caution: it only applies to the pages that carry this button, and only if the system does not ask for less motion.

Room to breathe

Some text, so that the page is long enough to scroll and the appearance of the button is noticeable.

The generator produces a static site: each page is a complete HTML file, served as is. No hydration step, no bundle to download before reading. That is what lets a component like this one be nothing but a link and two style rules.

A version lives on its own branch. The working branch keeps the sources, the version branch keeps the output. The two never mix, and going back to an old version does not require rebuilding anything.

The shipped components all follow the same rule: they provide the structure, and the look is set at use. None of them embeds a hard-coded colour; all of them read the tokens of the active theme.

When a page needs interaction, the answer is first sought in native elements — details for expanding, a link for moving, a CSS transition for appearing. Only after that, and rarely, would a script be justified.

This constraint has a happy side effect: a page stays readable in ten years, because there is nothing that can stop working. No dependency to update, no interface that breaks with the next browser.

And a less happy side effect, better known in advance: what depends on the moment is frozen at build time. A page that shows “the offer ends tomorrow” will still say so in six months if the site has not been rebuilt. A scheduled build is enough to keep it right.