[๐ ] Turning GitHub Pages blog footnotes into popovers
โจ GPT-5.5โs Summary ใ
A record of reducing the friction of Kramdownโs default footnotes jumping from the body to the bottom references, while keeping the existing footnote structure and turning body footnote links into a [1]-style popover UI.
As soon as I started using footnotes properly, the discomfort became obvious.
When I deal with external articles or source material on the blog, I now attach Kramdown footnotes next to the relevant body text. A post like The unprecedented ballot shortage, anger, and the damage caused by extremists had a lot of factual points, so it ended up with quite a few footnotes.
But when I actually read it, the flow felt bad.
When I clicked a footnote number in the body, no popup appeared. The page moved all the way down to the References section at the bottom. As a default behavior, that is correct. Kramdown normally builds footnotes that way. But in a long post, it is easy to lose the place I was reading.
The footnote number shape was awkward too.
If only tiny numbers like 1 2 3 4 are attached, they are hard to tap. It is even worse on mobile. Accurately tapping a small floating number in the middle of body text takes more attention than it should.
So this time I changed the footnote system a little.
In the body, footnotes now look like [1], [2], [3], and tapping them opens a small popup instead of moving to the bottom.
I did not change the Kramdown structure
I did not want to change the Markdown syntax or the way footnotes are generated.
Right now I write footnotes like this.
Body sentence.[^source]
[^source]: Source description and link
That should stay.
From the writing side, I use something close to standard Markdown syntax, and when Jekyll builds the site, Kramdown creates the footnote HTML. The bottom References section remains too. If I replaced that whole structure, I would have to touch existing posts and translated posts as well.
So the rule for this work was simple.
Keep the writing format as it is.
Keep the bottom footnotes generated by Kramdown.
Change only the display and click behavior of body footnote links.
In other words, keep the original data and fallback, and improve only the reading experience.
I made footnote numbers look like [1]
First I changed the CSS.
Kramdown gives body footnote links the a.footnote class. I made that link behave like a small inline-flex button, then added square brackets with ::before and ::after.
As a result, body footnotes now look like this instead of a single number.
[1] [2] [3]
I also widened the tappable area a little.
If it looks like a loud button, it breaks the rhythm of the text. But if it remains a tiny number, it is hard to click. So I added only a thin border and a subtle background, while keeping the text smaller than the body copy.
Because this blog has both light and dark modes, I did not hard-code the colors. I matched the existing Sass variables.
$primary-color
$background-color
$border-color
$text-color
This blog already loads customOverride.scss after both the light and dark skins. So I added the footnote styles to _sass/custom/customOverride.scss instead of editing the theme source directly.
Clicking creates a popup
Next was JavaScript.
Previously, SmoothScroll was attached to every #hash link. A footnote link is also an internal link to something like #fn:..., so clicking it smoothly moved the page downward.
This time I intercepted only body footnote links first.
The target is this.
.page__content a.footnote[href^="#fn"]
When clicked, the script blocks the default hash movement, finds the already-rendered item in the bottom footnote list, and clones its content. The bottom footnote contains a reversefootnote link back to the body, but that is not needed inside the popup, so I remove it.
The flow is this.
Click a body footnote
-> read the target id from href
-> find the bottom footnote li
-> clone the content
-> remove reversefootnote
-> insert it into the popup
-> calculate the position near the footnote link
Because the hash is not changed, the URL does not get messy. The page does not jump to the bottom either.
There are three ways to close it.
Click the same footnote again
Click outside the popup
Esc or the close button
For keyboard users, I also added aria-haspopup="dialog" and aria-expanded. The popup itself uses role="dialog". I would not call this a perfect accessibility component, but it is at least better than a floating div with no semantics.
I kept it inside the viewport on mobile
Positioning matters for a footnote popup.
Showing it right below the body link feels natural, but near the right edge or on mobile widths it can easily spill outside the screen.
So when positioning it, I force a margin inside the viewport.
Minimum 12px on the left
Minimum 12px on the right
If there is not enough space below, show it above
If still constrained, clamp it inside the viewport
The popup width is not fixed either.
width: min(30rem, calc(100vw - 1.5rem));
On desktop, it does not become too wide. On mobile, it does not become wider than the screen.
I also added max-height and overflow: auto for long footnotes. The intent is to avoid letting the popup cover the whole screen when an external article title or link is long.
I regenerated the minified file too
In this blog, assets/js/_main.js is the source file, and the deployed site reads assets/js/main.min.js.
So after editing the JS, I regenerated the minified file and source map with the Rake task.
bundle exec rake js
If I forget that step, the local source can look fixed while the real site still serves the old JavaScript. For this kind of work, the source file and the deployed file have to be checked together.
What I checked
I checked it like this.
node --check assets/js/_main.js
bundle exec rake js
bundle exec jekyll build
Then I opened an actual post with many footnotes through a local static server.
I checked these points.
Do footnote links appear as [1]?
Does the URL hash stay unchanged after clicking?
Does the page avoid jumping to the bottom references?
Does the popup appear?
Does the popup contain the bottom footnote content?
Does the popup stay inside the screen on mobile width?
On desktop, the bottom footnotes were far down the document, but after clicking a footnote the scroll stayed near the body text. On mobile width, the popup also stayed inside the screen.
It is a small feature, but the reading feel changed a lot
This is not a huge feature.
There is no data model, no routing, no new page. It simply makes existing footnote links easier to see and opens a popup when they are clicked.
But the reading feel changes quite a bit.
Especially in a post with many factual claims, footnotes are not decoration. When a reader wonders, โWhere did this come from?โ, they should be able to check immediately. If checking throws them to the bottom of the post and then makes them return to the body, footnotes quickly become annoying.
Now, while reading the body, the reader can tap [1], check the source, and close it.
The bottom References section still remains. Anyone who wants to review all sources at the end can still scroll down.
That was the level I wanted.
Keep the Markdown writing format. Keep the Jekyll/Kramdown default structure. Make only the readerโs fingers and eyes less tired.
Small improvements like this need to keep accumulating on the blog.
Leave a comment