Cocoonでサイドバー目次を「現在地ハイライト+自動追従」にする方法【長文記事対策】

ブログ運営メモ

5,000文字、8,000文字、1万文字。情報量の多い記事は、SEOでも評価されやすく、読者にとっても価値があります。

しかし同時に、こんな問題が起きます。

  • 今どこを読んでいるのか分からない
  • 文章がどれくらい残っているのか見通せない
  • なんとなく「長い」と感じて疲れる

“現在地が見えないこと” が、読者のストレスになるのです。

そこで今回、サイドバー目次に「現在地ハイライト+自動追従」を実装するカスタマイズを行いました。

読んでいるセクションが目次で常に強調表示され、目次が長くても自動で追いかけてくれる。

つまり、

  • 読者は迷わない
  • どこまで読み進めたか直感的に分かる
  • 「まだこれだけある」が見える

長文記事の“途方もなさ”が消えます。

今回は「エックスサーバー ✖ WordPress無料テーマCocoon」という環境で実装しました。汎用性はあると思うので、都度、ご自身の環境に置き換えてください。

実装するとどうなる?

まずは、今回の「現在地ハイライト+自動追従」を実装するとどのようになるか、をおさらいします。

  • 読んでいるセクションの目次がハイライトする
  • 目次が長い場合、自動でスクロール追従する
  • 読者が「今どこにいるか」を常に把握できる

このようなメリットがあり、長文記事との相性が抜群です。

手順の全体像(ざっくり)

まずはざっくりと作業の手順を確認してください。コードはコピペでOK。ですが、念の為にバックアップは必須でお願いします。

  1. サイドバーに目次を設置
  2. CSS追加
  3. Cocoon本体のfooter.phpをChildへコピー
  4. JSをfooter.phpに追加

それでは各作業を詳しく解説していきます。

① サイドバーに目次を追加する

WordPress管理画面より:外観 → ウィジェット

「サイドバースクロール追従」に 目次ウィジェットを追加します。

※Cocoonの大元設定と設定(目次表示の深さ)を合わせる必要があります。例えば大元でh3まで表示する設定にしているのに、ウィジェットではh2までにするとミスマッチが起こり、ハイライトが正しく動作しません。目次表示の深さは、Cocoon大元設定と合わせてください。

② 追加CSSを設定する

WordPress:外観 → カスタマイズ → 追加CSS に以下を追加します。コピペしてください。

目次が長い場合でもスクロールできるようにしています。

#sidebar-scroll .widget.widget_toc .toc-content{
  max-height: 55vh;
  overflow: auto;
}#sidebar-scroll .widget.widget_toc a{
  display: block;
  padding: 6px 0 6px 12px;
  text-decoration: none;
  border-left: 3px solid transparent;
  transition: background .2s ease, border-color .2s ease;
}#sidebar-scroll .widget.widget_toc a.is-active{
  background: rgba(59,130,246,0.12);
  border-left: 3px solid #3b82f6;
  font-weight: 600;
}

③ Cocoon本体のfooter.phpをChildにコピーする

※もともとChild側にfooter.phpがある場合はこの手順はスキップしてください。また、footer.phpでなくてもJavaScriptを追記できるファイルがあればそれで結構です。その場合もこの手順は飛ばしてOKです。

テーマ本体を直接編集すると、アップデート時に上書きされます。

必ず子テーマに新規追加、もしくは上書きしてください。

エックスサーバーでの作業手順

  1. エックスサーバーにログイン
  2. サーバーパネル → ファイルマネージャ
  3. 該当ドメインを開く。
  4. /public_html/wp-content/themes/cocoon-master/footer.php
    をコピー
  5. /public_html/wp-content/themes/cocoon-child-master/footer.php
    に貼り付け(コピー先を変更)

これでChild側に新規追加されます。

④ footer.phpにJSを追加する

WordPress管理画面:外観 → テーマファイルエディター → Theme Footer(footer.php)

</div><!-- #container --> の直前に以下のJSコードを追加します。

追加JSコードを設定する

<script>
document.addEventListener("DOMContentLoaded", () => {
const toc = document.querySelector("#sidebar-scroll .widget.widget_toc");
if (!toc) return; const tocScroll = toc.querySelector(".toc-content") || toc; const links = Array.from(toc.querySelectorAll('a[href^="#"]'))
.filter(a => a.getAttribute("href").length > 1); const items = links.map(a => {
const id = decodeURIComponent(a.getAttribute("href").slice(1));
const el = document.getElementById(id);
return el ? { id, el, a } : null;
}).filter(Boolean); if (!items.length) return; const OFFSET = 160;
let currentId = null; function clearActive(){
links.forEach(a => a.classList.remove("is-active"));
} function keepActiveVisible(activeLink){
if (tocScroll.scrollHeight <= tocScroll.clientHeight) return; const cRect = tocScroll.getBoundingClientRect();
const aRect = activeLink.getBoundingClientRect();
const padding = 14; if (aRect.top < cRect.top + padding ||
aRect.bottom > cRect.bottom - padding) {
activeLink.scrollIntoView({
block: "center",
inline: "nearest",
behavior: "smooth"
});
}
} function setActive(id){
if (id === currentId) return;
currentId = id; clearActive();
const hit = items.find(x => x.id === id);
if (!hit) return; hit.a.classList.add("is-active");
keepActiveVisible(hit.a);
} function update(){
let candidate = items[0]; for (const it of items) {
const top = it.el.getBoundingClientRect().top;
if (top <= OFFSET) candidate = it;
else break;
} setActive(candidate.id);
} let ticking = false;
function onScroll(){
if (ticking) return;
ticking = true;
requestAnimationFrame(() => {
update();
ticking = false;
});
} window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", onScroll, { passive: true });
window.addEventListener("load", onScroll); update();
});
</script>

固定ヘッダーがある場合

固定ヘッダーがある場合は、本文の表示と見出しのハイライトのタイミングがずれることがあります。そのような場合は、以下の数値を変更して調整してください。一般的な固定ヘッダーの場合は240くらいにするとちょうどいいかもしれません。

const OFFSET = 160;

実装作業は以上で終了です。

なぜこの実装が重要なのか?

長文記事は情報量で価値を出せます。

しかし同時に、ユーザーにとっては長文を読むことは大変な作業です。ただでさえ大変なのに以下のようなストレスをそのままにすると離脱率も上がってしまうでしょう。

  • どこを読んでいるのか分からない
  • 終わりが見えない

このストレスを少しでも緩和してもらおうとするのが今回の「現在地ハイライト+自動追従」実装です。

読書の現在地が可視化されると、以下のようなメリットが期待できます。

  • 読者は安心する
  • 読み進めやすくなる
  • 離脱が減る

UX向上は、結果的にSEOにも好影響です。

まとめ

今回やったことは4つ。

  1. 目次をサイドバー追従に設置
  2. CSSで見た目調整
  3. footer.phpを子テーマへコピー
  4. JSで現在地判定+自動追従

長文を書くブロガーにとって、かなり効果の高い改善施策だと思います。

本記事のコピペを利用してもらえると、実際の作業はそれほど難しくないと思うので、ぜひお試しください。

コメント

タイトルとURLをコピーしました