楽天セール開催中!ポイント最大11倍! セール会場へ

WordPress│スマホ追従目次ボタンのカスタマイズ

幅781px以下で画面右下に表示する、手動リンク方式の追従目次です。

detailsとsummaryで開閉でき、JavaScriptはリンク選択後とEscapeキーで閉じる処理を補助します。

旧版の端末判定・隠したチェックボックス・全アンカーへの処理は使いません。

目次

著者

WEB制作をしているデジタルノマド
WordPressのカスタマイズが好きで、色々と自作しています。

WordPressのカスタマイズに困ったらご相談ください!

動く見本

スマートフォン幅では右下の「この記事の目次」を開けます。

PC幅では表示しません。

この見本は本記事内の「設置方法」「確認と戻し方」へ移動します。

自動的に見出しを抽出する機能ではありません。

この記事の目次

設置方法

変更前に対象記事の本文と、追加先のCSS・JavaScriptの内容を保存します。

旧mobile_toc_widgetやfoot_customtagsを導入済みなら、その設置場所も控え、旧目次と今回の目次を併用しないようにします。

対象記事のカスタムHTMLブロックへHTMLを1組だけ置きます。

リンク先の各見出しにブロック設定のHTMLアンカーを指定し、hrefの値と一致させます。

同じIDを複数の見出しに付けないでください。

見出しを追加・削除したりHTMLアンカーを変更したりした場合は、目次側のリンクも手動で更新します。

<details class="waza-mobile-toc">
<summary>この記事の目次</summary>
<nav aria-label="この記事の目次"><ul>
<li><a href="#waza-toc-install">設置方法</a></li>
<li><a href="#waza-toc-check">確認と戻し方</a></li>
</ul></nav>
</details>

CSSは子テーマのスタイルシートなどへ追加します。

wp_is_mobileによる出し分けは行わず、画面幅で表示するため、PC向けHTMLがキャッシュされてもHTML自体は共通です。

.waza-mobile-toc { display: none; }
@media (max-width: 781px) {
  .waza-mobile-toc {
    display: block; position: fixed; right: 12px;
    bottom: calc(12px + env(safe-area-inset-bottom));
    z-index: 90; width: min(300px, calc(100vw - 24px));
    background: #fff; color: #222; border: 2px solid #766028;
    border-radius: 8px; box-shadow: 0 2px 12px #0002;
  }
  .waza-mobile-toc summary { padding: 12px; cursor: pointer; font-weight: bold; }
  .waza-mobile-toc nav { max-height: 50vh; overflow-y: auto; padding: 0 12px 12px; }
  .waza-mobile-toc a { display: block; padding: 8px; color: #173b65; }
  .waza-mobile-toc :focus-visible { outline: 3px solid #173b65; outline-offset: 2px; }
}

JavaScriptは対象ページで1回読み込みます。

JSファイルへ置く場合はscriptタグを付けません。

カスタムHTMLへ入れる場合のみscriptタグで囲み、保存後に削除されていないか確認します。

掲載コードは初期化時点の目次とリンクに処理を登録します。

Pjaxや別のスクリプトが後から追加した目次・リンクへ自動的に登録し直す処理はありません。

(() => {
  const init = () => document.querySelectorAll('.waza-mobile-toc').forEach(toc => {
    const summary = toc.querySelector('summary');
    if (!summary || toc.dataset.wazaReady) return;
    toc.dataset.wazaReady = '1';
    toc.addEventListener('keydown', event => {
      if (event.key === 'Escape' && toc.open) {
        toc.open = false; summary.focus(); event.preventDefault();
      }
    });
    toc.querySelectorAll('a[href^="#"]').forEach(link => link.addEventListener('click', () => {
      let id; try { id = decodeURIComponent(link.hash.slice(1)); } catch { return; }
      const target = document.getElementById(id);
      if (!target) return;
      toc.open = false;
      if (!target.hasAttribute('tabindex')) target.setAttribute('tabindex', '-1');
      target.focus({preventScroll: true}); // スクロール自体は標準のアンカー移動
    }));
    const media = matchMedia('(max-width: 781px)');
    media.addEventListener('change', () => {
      if (!media.matches) toc.open = false;
    });
  });
  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init, {once: true});
  else init();
})();

確認と戻し方

スマホ幅で開閉、リンク先への移動、TabとEnter・Space、Escapeで閉じてsummaryへフォーカスが戻ることを確認します。

これは非モーダルな目次なので、開いている間もページ内のほかの要素を操作できます。

details自体の開閉と通常のアンカーリンクが動いても、JavaScriptが正しく読み込まれた証拠にはなりません。

Escapeで閉じる動作と、リンク選択後に目次が閉じて見出しへフォーカスが移る動作も分けて確認してください。

780px前後だけでなく781pxと782px、横向き、ブラウザーの拡大でも確認してください。

テーマの固定ヘッダーに見出しが隠れる場合は、見出し側のscroll-margin-topを実際のヘッダー高さに合わせます。

Cookie表示や他の固定ボタンとの重なりも設置先で調整します。

実端末のタッチ操作、読み上げ、すべてのテーマ・広告・最適化プラグインとの組み合わせは未検証です。

戻すときは今回のHTML・CSS・JavaScriptを外します。

旧mobile_toc_widgetやfoot_customtagsとは併用せず、旧コードの設置場所を控えてから切り替えます。

旧ウィジェット方式と旧外部コード集は今回の見本と未同期です。

スマホ幅390pxで開いた追従目次の実画面
2026年10月1日、公開ページを幅390pxで操作して撮影。
  • URLをコピーしました!

実装を任せたい方へ

WordPressのカスタマイズ代行

ブロックの追加、テーマの改修、管理画面の調整など、記事で紹介している内容の実装を承ります。1時間 ¥8,000〜(税込)。

WAZAの有料記事のサブスクリプションも開始しました。

サービス

Service

WordPressサイトのカスタマイズのサービスに関心がありましたら、ぜひ詳細をご覧ください。

目次