Hugoブログの見出しアンカーをQiita風に変更し本文行間をnote.com風に調整した

Redesigning Heading Anchor Links Qiita-Style and Tuning Paragraph Spacing to Match note.com in Hugo

* 本ページはプロモーションが含まれています

このブログの見出し(h2など)の末尾に常時表示されていた錨アイコン(fa-anchor)のアンカーリンクが少しダサく感じていた。
Qiita の見出しデザインを参考に、SEOへの影響も含めて表示方式を検討し直すことにした。ついでに本文の行間・余白も note の記事スタイルに合わせて調整した。
コードの修正はほぼ手作業ではなく生成AIに任せ、Playwright MCPでローカルの見た目を確認しながら進めた作業の記録。


本文の行間・余白調整

note.com に掲載されている記事を参考に、static/css/custom.css.blog-post p / .blog-post li を見直した。

参考記事との比較

Playwright MCP で自分のサイトと note.com 両方の getComputedStyle を直接計測し、数値で突き合わせた。

項目note.com(PC)変更後(PC)note.com(390px)変更後(767px以下)
フォントサイズ18px18px(変更なし)16px16px
line-height36px(2.0倍)36px32px(2.0倍)32px
段落margin上下36pxmargin: 0 0 36px上下30pxmargin: 0 0 30px

変更内容

  • line-height1.82 に変更
  • 段落に margin: 0 0 36px を追加
  • 767px以下のブレークポイントで font-size: 16px / line-height: 2 / margin: 0 0 30px に縮小するメディアクエリを追加

変更しなかった項目

左右の余白(パディング)は、実測で note.com が 16px・現状 15px とほぼ同じだったため変更しなかった。

検証

hugo server -Dlocalhost:1313)で PC 幅・モバイル幅(390px)の両方を Playwright MCP で確認し、スタイル反映後にスクリーンショットで見た目を確認した。検証用の一時ファイル(.playwright-mcp/、スクリーンショット PNG)は作業完了後に削除した。


見出しアンカーリンクをQiita風に変更

Qiita の記事ページをブラウザで直接検証(CDP で getComputedStyleforcePseudoState を使用)し、次の実装がベースであることを確認した。

  • アイコンは fa-link(鎖)。position: absolute; left: -33px; で見出し左外側に配置
  • 通常は display: none、見出しホバー時のみ flex で表示

これを踏まえ、以下の変更を行った。

layouts/_default/single.html

- {{ .Content | replaceRE "(<h[1-9] id=\"([^\"]+)\".+)(</h[1-9]+>)" "${1}&nbsp;<a class=\"headline-hash\" href=\"#${2}\"><i class=\"fas fa-anchor\"></i></a> ${3}" | safeHTML}}
+ {{ .Content | replaceRE "(<h[1-9] id=\"([^\"]+)\".+)(</h[1-9]+>)" "${1}<a class=\"headline-hash\" href=\"#${2}\" aria-label=\"見出しへのリンク\"><i class=\"fas fa-link\" aria-hidden=\"true\"></i></a>${3}" | safeHTML}}
  • アイコンを fa-anchorfa-link に変更
  • aria-label を追加してスクリーンリーダー対応を改善
  • 位置調整を絶対配置に切り替えるため &nbsp; を削除

static/css/custom.css

.blog-post h1,
.blog-post h2,
.blog-post h3,
.blog-post h4:not(.see-also),
.blog-post h5,
.blog-post h6 {
  position: relative;
}

.blog-post h1,
.blog-post h2 {
  margin-top: 2.4em;
  padding-bottom: 0.25em;
  border-bottom: 1px solid rgba(0, 0, 0, 0.12);
}

.headline-hash {
  position: absolute;
  top: 0;
  left: -1.3em;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.3em;
  height: 100%;
  color: rgba(0, 0, 0, 0.6);
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.15s ease, color 0.15s ease;
}

.headline-hash .fa-link {
  font-size: 0.6em;
}

.headline-hash:hover {
  color: #0366d6;
}

.blog-post h1:hover .headline-hash,
.blog-post h2:hover .headline-hash,
.blog-post h3:hover .headline-hash,
.blog-post h4:hover .headline-hash,
.blog-post h5:hover .headline-hash,
.blog-post h6:hover .headline-hash,
.headline-hash:focus {
  opacity: 1;
}

/* 992px未満はオフセット列が無く見出し左側にアイコンを置く余白が無いため、末尾表示にフォールバックする */
@media only screen and (max-width: 991px) {
  .headline-hash {
    position: static;
    display: inline-flex;
    width: auto;
    height: auto;
    margin-left: 0.4em;
    opacity: 0.4;
  }
}

h1・h2 には下線を追加してセクションの区切りを明確にした。
Qiita は display: noneflex の切り替えでキーボードフォーカス時に要素へアクセスできない作りだったため、そこは踏襲せず opacity 制御に変更し、:focus でも表示されるようにした。
Bootstrap のグリッドで記事本文列に左オフセット(col-md-offset-1 / col-lg-offset-2)が付くのは 992px 以上のみのため、992px 未満では絶対配置をやめて見出し末尾にインラインで薄く常時表示するフォールバックを @media (max-width: 991px) で用意した。


検証

  • ローカルの hugo server -D で表示を確認した
  • CDP の forcePseudoState でホバー状態を強制し、デスクトップ幅(1280px)で見出し左に鎖アイコンが出現することをスクリーンショットで確認した
  • Playwright MCP でも同様にホバー動作を確認した
  • モバイル幅(390px)でアイコンが末尾に薄く常時表示されるフォールバックを確認した
  • ReadLints で CSS / テンプレートの構文エラーが無いことを確認した

まとめ

見出しアンカーの fa-anchorfa-link に置き換えてホバー時のみ表示する Qiita 風デザインに変更し、あわせて本文の行間・段落マージンを note.com のスタイルに実測ベースで合わせた。
見出し左側への絶対配置は 992px 以上のレイアウトでしか成立しないため、狭い画面では見出し末尾へのフォールバック表示を用意して破綻を避けた。

今まで、自分でもちょっと行間が狭いなと思っていたので、少しは見やすくなったかな?


See also