Scratch – footnotes
- Posted
6 June 2025
Continuing my incremental NetNewsWire theme build. Version 4 Scratch – overflow handles styling to prevent the common causes of content horizontal overflow. Version 5 digs into styling NetNewsWire’s popover footnote implementation.
NetNewsWire footnotes
Along with some core CSS, NetNewsWire injects a little JavaScript. One of the functions of this code is to enhance footnotes that follow the requisite pattern. Displaying the referenced content in an in-place popover when the anchor is clicked. Saving us the effort of scrolling up and down to read the referenced text.
The inline footnote anchors are wrapped in a div to provide a positioning context for the referenced footnote:
<div class="newsfoot-footnote-container">
<a href="#fn:000" class="footnote">1</a>
<div class="newsfoot-footnote-popover">
<div class="newsfoot-footnote-popover-arrow"></div>
<div class="newsfoot-footnote-popover-inner">
<!-- Footnote content -->
</div>
</div>
</div>
The anchors
Typically a digit wrapped in a link to the footer note. NetNewsWire bakes in some core CSS to style these as little capsule buttons. These styles are readily overridden. For now I’m sticking with the providing the colour as appropriate for a theme.
To ensure a little space between the anchor and the preceding text, I applied a little left margin to the container div. This got a little complicated when I realised the container div is not inserted until you click the link. Making the anchor visibly jump on click.
Remedy: add the margin to both the anchor and the container – removing the anchor margin when it was wrapped.
:root {
--footnote-margin: 0.3rem;
}
.newsfoot-footnote-container {
margin-inline-start: var(--footnote-margin);
--contained: 0;
}
a.footnote {
color: Canvas;
background-color: var(--link-color);
margin-inline-start: var(--contained, var(--footnote-margin));
font-weight: bold;
}
Text and link colour variable refactor
Applying the link colour to the footnote anchor background provided cause for a light refactor to make it a variable.
:root {
color-scheme: light dark;
--text-color-contrast: 65%;
--link-color-contrast: 75%;
--text-color: color-mix(in oklab, CanvasText var(--text-color-contrast), Canvas);
--link-color: color-mix(in oklab, CanvasText var(--link-color-contrast), Canvas);
--visited-link-color: oklch(50.3% 0.282 295);
}
Mistakes made
Attempting to style the footnotes I realised I had messed up.
Drunk on the power of a clean CSS selector; I had applied the nuclear option in version 4 – negating inline styles on divs and spans. Doing so removed the author’s inline styles, while also making footnotes difficult to style without a reciprocal !important escalation.
To enable the footnotes to be positioned it was necessary to tighten the beam and direct it away from our footnote divs:
.articleBody {
span[style],
div[style]:not([class^="newsfoot"]) {
all: revert !important;
}
}
The popovers
Like the anchors, the core NNW CSS for popovers leaves colours for the theme. The three divs overlap to simplify the CSS necessary to make the speech bubble style.
.newsfoot-footnote-popover {
padding-inline: 0;
border: solid 0.125em currentColor;
background-color: Canvas;
}
.newsfoot-footnote-popover-arrow {
display: block;
background-color: Canvas;
outline: solid 0.125em currentColor;
outline-offset: -0.0625em;
}
.newsfoot-footnote-popover-inner {
background-color: Canvas;
}
The arrow is a rotated positioned square tucked between the other two divs.
A too-wide arrow can look broken when the anchor is against the right hand edge. Using outline with outline offset provides a little additional control over how the arrow point is drawn.
I had to display:block
it for reasons…
More regret
It took me a moment to realise the popover arrow was not displaying because it was one of those empty decorative divs I had explicitly hidden. Reducing the specificity of the :empty
selector to ease the override, hence display:block
above.
Hid empty paragraphs too while I was at it.
:is(p,div):where(:empty) {
display: none;
}
If these styles continue to prove troublesome I’ll consider removing them altogether. I’m overstating the mistakes and regrets for forced drama. This is an iterative push pull process.
The shrinking nested paragraph mystery
All the themes I’ve checked present footnote popover text smaller than the surrounding body text. I can imagine this being deliberate, but I’ve found no explicit cause for the size shift.
For now I’m fudging it with this cursed code:
p p {
font-size: 120%;
}
Another case of small svg intent
I’m punting on the subject of a figure being more likely to be the <img>
than the <svg>
if both a present.
figure:has(img) svg,
Install
To enable a quick switch between different versions of this theme I’ve generated a zip of each version – incorporating the version number in the name:
Get the latest version on the Scratch project page.
Next up
Maybe version 6 will tackle tables. No promises.