Skip to the page
TACTILE UI

Kit part · Scroll areas

Page loupe

A map of the whole page, for the corner beside it. A machined groove holds the page drawn small, a glass loupe rides over the part in the window, and the page’s section headings are printed beside the groove at their own height, the one you are reading lit. Drag the loupe or press the groove to move; the headings are links.

Element
<tui-page-loupe>
Needs
kit.css + kit.mjs
Rules
page-loupe.rules.md · 5
Finishes
Aluminium · Graphite · Porcelain · Black
Volumes
Tactile · Quiet
On this page
  1. Variants
  2. Every state, at once
  3. API
  4. Markup
  5. Accessibility
  6. How it’s built
  7. Rules
  8. Related parts
01

Variants

4.2.1

Fixes the slow query on db-2 that took the first canary out. p95 is back under 200 ms.

4.2

Canary gates can hold on errors as well as latency. The deploy board shows every region on one line.

  • Signing keys can be revoked from the console.
  • The audit log exports to cold storage every night.

4.1

Release notes go to the team by email when a release is live everywhere.

4.2.1

Fixes the slow query on db-2 that took the first canary out. p95 is back under 200 ms.

4.2

Canary gates can hold on errors as well as latency. The deploy board shows every region on one line.

  • Signing keys can be revoked from the console.
  • The audit log exports to cold storage every night.

4.1

Release notes go to the team by email when a release is live everywhere.

Release notes

When this runs

Lode takes a canary out by itself when p95 latency passes 800 ms for three minutes, or when errors pass one per cent of requests. This runbook is for the person on call when that happens.

The first five minutes

  1. Look at the deploy board. The canary shows red and the release is held.
  2. Open the canary’s dashboard and note the minute it rolled back.
  3. Say in the releases channel that the canary is out and that you are on it.

Find the cause

Most rollbacks in the last year came from one of three places: a slow query, a cache that went cold, or a service outside Lode that timed out. Start with the database and list the slowest queries of the last quarter of an hour:

lode db top --host db-2 --since 15m --by p95

If one query is far slower than the rest, it is almost always the cause. The release notes say which change added it.

Ship the fix

Cut a patch release from the release branch, not from main, so nothing else goes out with it. The canary takes five per cent of traffic, then 25, then all of it, one region at a time.

lode release cut --from release/4.2 --patch
lode canary start --steps 5,25,100

Afterwards

Write two lines in the incident log: what rolled back and what fixed it. If the same cause comes back within a month, it gets a ticket of its own.

A narrow groove · --pl-rail
02

Every state, at once

Both finishes, side by side. Hover, pressed and focus are forced with .is-hover, .is-down and .is-focus; checked and disabled are real.

03

API

NameKindValuesWhat it does
<tui-page-loupe>elementfor · labelThe corner: its label and how far through the page you are, the groove with the page drawn on its floor, and the page’s section headings beside it.
forattributean idWhat it maps. An article that scrolls with the window, or a box that scrolls on its own, which it then follows instead.
labelattributetextPrinted over the groove and given to the list of headings. On this page, by default.
offsetattributepxThe height of a bar that sticks over the page, so the loupe covers what is really in view.
mediaattributea selectorWhat else to draw as a box, besides code and pictures: a demo, a table, a card.
headsattributea selectorWhich headings name the sections. Every h2 with an id, by default, but not one in a dialog.
.tui-page-loupe__marksclassbuiltThe headings, as links, each at its own height and pushed down where two would touch, a leader drawn back up to where it belongs.
aria-current="location"attributeon a headingThe section being read: its heading lit, with the green lamp beside it.
--pl-railcustom propertylengthThe groove’s width: 72px, and 60px in a narrower corner.
--progresscustom property0 to 1How far through the page the reader is, written on the element for anything of yours that wants it.
refresh()methodnoneDraw the map again now. It does so by itself whenever the page or the corner changes size.
pageLoupeMarks · pageLoupeAt · pageLoupeCurrentfunctionkit.mjsThe rules, pure: where each heading’s label goes, how far through the page the window is, and which section is being read. The groove and the loupe use the Loupe scroll’s own.
04

Markup

<article id="article">
  <h2 id="runs">When this runs</h2>
  <p>…</p>
  <h2 id="first">The first five minutes</h2>
  …
</article>

<aside class="corner">
  <tui-page-loupe for="article" label="On this page" offset="64"></tui-page-loupe>
</aside>
import '/kit/kit.mjs';   // defines <tui-page-loupe>

// It redraws itself when the page or its corner changes size.
// Drew the page again in place, with new content? Ask it to look again:
document.querySelector('tui-page-loupe').refresh();

// Only some headings name your sections? Say which:
// <tui-page-loupe for="article" heads=":scope > section > h2">

Needs kit.css and kit.mjs. How to install the kit.

05

Accessibility

  • The headings are a list of links, named by the label, so the keyboard and a screen reader reach every section from the corner.
  • The section being read is marked with aria-current="location", so it is said as well as lit.
  • The groove and the loupe are a picture and a pointer’s shortcut, as a scrollbar is: hidden from assistive technology and out of the tab order, and there is nothing on them that scrolling does not reach.
  • The percentage beside the label is for the eye only; the page’s own scrolling already tells a screen reader where it is.
  • A press on the groove glides to its place; with reduced motion it jumps.
  • Without the script there is no corner; the docs keep a list of sections in the page itself for that, and for narrow screens.
06

How it’s built

It is the Loupe scroll’s rail, pointed outwards. The map is the page’s own line boxes: for each block a Range round its contents gives one client rect for every run of text, and loupeLines joins each line’s runs into one bar, scaled down the groove to fit the whole page and across it to fit the line. Code, pictures and whatever media names are boxes; a part of the page that is sticky, a demo held beside the text, is left off, because it is not on the page’s run. loupeWindow places the glass over what the window shows, less the offset of a sticky bar, and its lens holds a copy of the map scaled 1.4 times about the loupe’s middle. The headings are placed by pageLoupeMarks, and pageLoupeCurrent lights the last one to pass a line a third of the way down the window. A ResizeObserver on the page and the groove redraws the map, and refresh() finds the page again by its id after it is drawn in place.

07

Rules

page-loupe.rules.mdIn the brain

For a long page read from the top down, in a corner that stays beside it.

5 rules in this file, with the foundations they rest on and the anti-patterns that break them. Full rules ship in the brain with the Pass.

08

4.2.1

Fixes the slow query on db-2 that took the first canary out. p95 is back under 200 ms.

4.2

Canary gates can hold on errors as well as latency. The deploy board shows every region on one line.

  • Signing keys can be revoked from the console.
  • The audit log exports to cold storage every night.

4.1

Release notes go to the team by email when a release is live everywhere.

Loupe scroll

A scroll area whose scrollbar is a map of what it holds. A narrow machined rail runs beside the text with every line drawn small on its floor, headings darker and code as a box. A glass loupe rides over the part in view and shows it a little magnified. Drag the loupe to scroll, or press the rail to jump there; underneath it is a native scroll container.

  1. HubReserve raised to 20%
  2. Meter 2291Missed three readings
  3. HubMeter 2291 is back
  4. BatteryFull at 13.4 kWh
  5. GridExporting 2.1 kW at 15p
  6. CarBoost charge started

Scroll area

A region that scrolls, with its scrollbar made as a machined rail: a groove cut into the plate and a thumb like a fader cap riding in it. Scrolling itself is the browser’s own.

Page wheel

Pagination as a thumbwheel. A knurled wheel stands in a recess with a window in its face, and the page number rolls past it on a paper tape. A key either side steps by one. The keys are plain links, so it pages without any script; the wheel is what a script adds.

Docs
Finish
Volume