展開可能リスト機能 (collapsible-list)

1 概要

ネストされたリストを折りたたみ/展開可能にする機能です。HTML5 の <details>/<summary> 要素を使用して、JavaScript により動的に変換されます。

1.1 特徴

  • 子要素を持つリスト項目は、初期状態で折りたたまれます。
  • 項目をクリックすると子要素が展開されます。
  • ブラウザの「戻る」操作時には、折りたたみ/展開状態が復元されます。
  • ブラウザの JavaScript が有効である必要があります。
  • HTML5 ネイティブ要素を使用するため、スクリーンリーダー等に対応します。
  • 通常のリスト (.collapsible-list クラスなし) には影響しません。
  • 既に <details> 要素でラップされている項目は変換されません。
  • 深くネストされたリストでも正しく動作します。

2 クラス

2.1 collapsible-list

展開可能なリストを示す汎用クラスです。

<div class="collapsible-list">
<ul>
<li>親項目1
<ul>
<li>子項目1-1</li>
<li>子項目1-2</li>
</ul></li>
<li>親項目2</li>
</ul>
</div>

注意: このクラスは追加クラス (modifier class) として設計されています。既存のスタイルを上書きせず、展開機能のみを付与します。

3 使用方法

3.1 insert-toc での自動適用

\toc コマンドで生成される目次リストには、自動的に collapsible-list クラスが付与されます。

Markdown:

\toc depth=-1

生成される HTML:

<div class="collapsible-list">
<ul>
<li>📁 <a href="index.html">トップレベル</a>
<ul>
<li>📄 <a href="file.html">ファイル</a></li>
</ul></li>
</ul>
</div>

3.2 Markdown での手動使用

Pandoc の fenced div 記法を使用して、任意のリストに展開機能を付与できます。

::: {.collapsible-list}
- 親項目1
  - 子項目1-1
  - 子項目1-2
- 親項目2
  - 子項目2-1
:::

4 変換後の HTML 構造

JavaScript により、子要素を持つ <li> 要素が以下のように変換されます。

変換前:

<li>親項目
<ul>
<li>子項目</li>
</ul></li>

変換後:

<li>
<details>
<summary>親項目</summary>
<ul>
<li>子項目</li>
</ul>
</details>
</li>

5 スタイル

5.1 CSS 変数

.collapsible-list {
  /* 現時点ではデフォルトスタイルのみ */
}

.collapsible-list details > summary {
  cursor: pointer;
  list-style: none;
}

.collapsible-list details > summary::-webkit-details-marker {
  display: none;
}

5.2 展開マーカー

展開/折りたたみ状態を示すマーカーは、CSS の ::before 疑似要素で実装されます。Windows 11 エクスプローラー風のシェブロン (>) を CSS の border プロパティで描画しています。

  • 折りたたみ時: 右向きシェブロン >
  • 展開時: 下向きシェブロン
.collapsible-list details > summary::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  border-right: 2px solid #000;
  border-bottom: 2px solid #000;
  transform: rotate(-45deg);  /* 折りたたみ時: 右向き */
}

.collapsible-list details[open] > summary::before {
  transform: rotate(45deg);   /* 展開時: 下向き */
}

展開マーカーを持つ項目 (子リストを持つ <li>) は、Bullet (・) が非表示になります。これは CSS の :has() セレクタにより実現されています。

5.3 対象要素

JavaScript は以下の条件を満たす要素を変換します。

  1. .collapsible-list クラスを持つ要素の子孫
  2. <li> 要素
  3. 子要素として <ul> または <ol> を持つ

6 状態の保存と復元

折りたたみ/展開状態は sessionStorage を使用してブラウザの「戻る」操作時に復元されます。

6.1 動作仕様

  • 初回表示: すべての項目が折りたたまれた状態 (デフォルト)
  • ブラウザの「戻る」/「進む」: 以前の折りたたみ/展開状態が復元される
  • ページのリロード: 折りたたまれた状態に戻る (初回表示と同じ)
  • タブを閉じる: 保存された状態は破棄される (sessionStorage のため)

6.2 技術詳細

  • PerformanceNavigationTiming API を使用して、ナビゲーション種別 (back_forward) を判定します。
  • sessionStorage のキーは collapsible-state:{pathname} の形式で、ページごとに状態を管理します。
  • <details> 要素の toggle イベントを監視し、状態変更時に自動保存します。

7 関連ドキュメント