[Hugo] 見出しにアンカーリンクのボタンを表示する

2024-01-28 (日)

Hugo は、## などの見出しにアンカーリンクを自動設定してくれます。目次の出力 (Table of contentsTable) でアンカーリンクに飛べます。
しかし、見出しのテキストにマウスカーソルを乗せても、アンカーリンクは表示されません。
GitHub のようにアンカーリンクのアイコンボタンを表示する方法です。

環境

  • Hugo v0.121.1
  • Windows 11 Pro 22H2 22621.3007

前提

以下の方針で実装します。

  • 静的に処理して、HTML を出力する。
  • JavaScript を必要としない。
  • 独自の CSS を適用して、見た目や位置を変更できる。

結果

見出しにマウスカーソルを乗せるか、タップすると表示します。

image

(左側に表示させたかったので、左側の余白がギリギリになってしまいました…)

実装

ショートコード layouts/shortcodes/headline-anchor.html を作成します。

{{ . | replaceRE "(<h[2-9] id=\"([^\"]+)\">)(.+</h[2-9]+>)" `${1}<a class="headline-anchor" href="#${2}"><i class="my-class"></i></a>${3}` | safeHTML }}
  • <i class="my-class"> には、各自表示したいアイコンの class などを設定してください。

💡 正規表現の結果は、以下のようになります。
## 見出し {#anchor} という Markdown の場合

グループ該当の正規表現出力結果
${1}(<h[2-9] id=\"([^\"]+)\">)<h2 id="#anchor">
${2}([^\"]+)anchor
${3}(.+</h[2-9]+>)見出し</h2>

次に、single.html などのマークダウン記事を出力しているテンプレートで、{{ .Content }} を以下のように変更します。

{{ partial "headline-anchor.html" .Content }}

最後に、css に設定を追加します。

h2 > a.headline-anchor,
h3 > a.headline-anchor {
  visibility: hidden;
  margin-left: 0px;
  float: left;
  padding-right: 0px;
  margin-left: -18px;
  line-height: 1.15;
  text-decoration: none;
}

h2:hover > a.headline-anchor,
h3:hover > a.headline-anchor {
  visibility: visible;
}

css 設定例

  • h2 と h3 のみに設定します。
  • 見出しの左側に表示します。
  • マウスカーソルを乗せると表示します。
  • モバイルデバイスでは、タップすると表示します。

💡 モバイル表示時には常にアンカーリンクを表示するようにしたい場合は、以下のようにします。

  • visibility: hidden; の適用を画面幅に基づいて、条件付きにします。
  • ここでは .scss を使用した例です。
h2 > a.headline-anchor,
h3 > a.headline-anchor {
  @include tablet {
    visibility: hidden;
  }
  margin-left: 0px;
  float: left;
  ...
}

感謝

2024-01-28 (日)