[🛠] GitHub Pagesブログの脚注をポップアップに変える
✨ GPT-5.5の要約
Kramdownの標準脚注が本文から最下部の参考資料へ移動してしまう不便さを減らすため、既存の脚注構造は維持したまま、本文中の脚注リンクを[1]形式のポップアップUIに変えた記録。
脚注をきちんと使い始めたら、すぐに不便さが見えた。
ブログ記事で外部記事や資料を扱うときは、今は本文の該当箇所にKramdownのfootnoteを付けている。特に投票用紙不足という前代未聞の事件、怒り、極端主義者の弊害のような記事は事実関係が多く、脚注もかなり多かった。
ところが実際に読んでみると、流れがよくなかった。
本文の脚注番号を押すとポップアップが出るのではなく、ページ最下部の参考資料エリアまで移動した。標準動作としては正しい。Kramdownはもともとそういう脚注を作る。ただ、長い記事では読んでいた位置を見失いやすい。
脚注番号の見た目も微妙だった。
1 2 3 4のように小さな数字だけが付いていると押しにくい。特にモバイルではなおさらだ。本文の途中に浮いている小さな数字を正確に押すのは、思ったより神経を使う。
そこで今回は脚注システムを少し変えた。
本文では[1]、[2]、[3]のように見せ、押すと最下部へ移動せず、小さなポップアップが出るようにした。
Kramdownの構造は触らなかった
最初からMarkdownの文法やfootnoteの生成方式を変えたくはなかった。
今の記事ではこう書いている。
本文の文。[^source]
[^source]: 資料説明とリンク
この方式はそのまま維持するのが正しい。
書く側はMarkdown標準に近い文法を使い、JekyllがビルドするときにKramdownが脚注HTMLを作る。下部の参考資料エリアもそのまま残る。この構造まで入れ替えると、既存記事全体と翻訳記事まで触らなければならない。
だから今回の作業基準は単純だった。
記事の書き方はそのままにする。
Kramdownが作った下部脚注もそのまま残す。
本文の脚注リンクの表示とクリック動作だけを変える。
つまり、元データとfallbackは残し、読む体験だけを改善する方向だ。
脚注番号を[1]のように見せた
まずCSSを変えた。
Kramdownは本文の脚注リンクにa.footnoteクラスを付ける。このリンクを小さなinline-flexボタンのようにし、::beforeと::afterで角括弧を付けた。
結果として本文では、数字ひとつではなくこう見える。
[1] [2] [3]
指で押す領域も少し広げた。
大きく目立つボタンにすると本文のリズムが崩れる。とはいえ以前のように小さな数字だけだとクリックしづらい。そこで枠線と背景を薄く入れ、文字サイズは本文より小さく保った。
明るいモードと暗いモードの両方があるので、色はハードコードせず、既存のSass変数に合わせた。
$primary-color
$background-color
$border-color
$text-color
このブログではすでにcustomOverride.scssを明るいスキンと暗いスキンの後に共通で読み込んでいる。だからテーマ本体を直接触らず、_sass/custom/customOverride.scssに脚注スタイルを追加した。
クリックするとポップアップを作る
次はJavaScriptだ。
以前はすべての#hashリンクにSmoothScrollがかかっていた。脚注リンクも結局は#fn:...へ向かう内部リンクなので、押すとページ下部へなめらかに移動した。
今回は本文内の脚注リンクだけを先に捕まえた。
対象はこれだ。
.page__content a.footnote[href^="#fn"]
クリックすると、本来のハッシュ移動を止め、下部の脚注リストにすでにレンダリングされている内容を探して複製する。下部脚注の中には本文へ戻るreversefootnoteリンクが入っているが、ポップアップ内では不要なので削除した。
流れはこうだ。
本文脚注をクリック
-> hrefからtarget idを読む
-> 下部のfootnote liを探す
-> 内容をclone
-> reversefootnoteを削除
-> ポップアップへ挿入
-> 脚注リンク付近に位置を計算
ハッシュを変えないのでURLも汚れない。ページ最下部へ移動することもない。
閉じる方法は三つにした。
同じ脚注をもう一度クリック
ポップアップ外をクリック
Escまたは閉じるボタン
キーボード利用のためにaria-haspopup="dialog"とaria-expandedも付けた。ポップアップ自体にはrole="dialog"を入れた。完璧なアクセシビリティコンポーネントと言うほどではないが、意味のないdivが浮いているだけよりはましだ。
モバイルで画面外へ出ないようにした
脚注ポップアップは位置計算が重要だった。
本文リンクのすぐ下に出すと自然だが、画面右端やモバイル幅では簡単にはみ出す。
だから位置を決めるときにviewport内側のmarginを強制した。
左は最小12px
右も最小12px
下の空間が足りなければ上に出す
それでも足りなければviewport内へclamp
ポップアップ幅も固定幅ではなく、こうした。
width: min(30rem, calc(100vw - 1.5rem));
デスクトップでは広がりすぎず、モバイルでは画面より大きくならない。
長い脚注に備えてmax-heightとoverflow: autoも入れた。外部記事のタイトルやリンクが長くても、ポップアップが画面全体を覆わないようにするためだ。
圧縮ファイルも一緒に更新した
このブログではassets/js/_main.jsがソースで、実際の配信ではassets/js/main.min.jsを読む。
だからJSを直した後は、Rakeタスクで圧縮ファイルとsource mapを作り直した。
bundle exec rake js
これを忘れると、ローカルのソースだけ直って、実際のサイトでは古いJSが出続ける可能性がある。この種類の作業では、ソースファイルと配信用ファイルを一緒に見る必要がある。
確認したこと
確認はこうした。
node --check assets/js/_main.js
bundle exec rake js
bundle exec jekyll build
そして脚注が多い実際の記事をローカル静的サーバーで開いて確認した。
確認した内容はこれだ。
脚注リンクが[1]形式で見えるか
クリック後にURL hashが変わらないか
最下部の参考資料へ移動しないか
ポップアップが出るか
ポップアップ内に下部脚注の内容が入るか
モバイル幅でもポップアップが画面内に収まるか
デスクトップでは下部脚注の位置が文書のかなり下にあったが、脚注クリック後のスクロールは本文付近に留まった。モバイル幅でもポップアップは画面内に収まった。
小さな機能だが読む感覚はかなり変わった
今回の作業は大きな機能ではない。
データモデルもなく、ルーティングもなく、新しいページもない。ただ既存の脚注リンクを見やすくし、クリックしたらポップアップを出すだけだ。
それでも読む感覚はかなり変わる。
特に事実関係が多い記事では、脚注は飾りではない。読者が「この話はどこから出てきたのか」と思ったとき、すぐ確認できるべきだ。なのに確認しようとして記事の最下部まで飛ばされ、また本文に戻らなければならないなら、脚注はすぐ面倒なものになる。
今は本文を読みながら[1]を押せば、その場で確認して閉じられる。
下部の参考資料もそのまま残っている。記事の最後で資料をまとめて見たい人は、今まで通り最下部を見ればいい。
自分が欲しかったのはこの程度だった。
Markdownの書き方はそのまま。Jekyll/Kramdownの基本構造も生かす。読む人の指と目だけを少し楽にする。
小さくても、ブログにはこういう改善を積み重ねていく必要がある。
コメントする