<details><summary>で折りたたみ開閉ボタンを設置

(更新

クリックするとその詳細が表示される「折りたたみ開閉ボタン」を設置する際、以前まではJavaScriptで設定するのが一般的でした。

けれども、HTML5からは新しく<details>と<summary>が追加されたため、この二つのHTMLタグを組み合わせることで、JavaScriptを使用しなくても開閉ボタンを設定することができます。

この<details>タグの使い方については、<summary>タグとセットで使用します。

例えば、以下のように記載したとします。

<details><summary>タグのサンプル

<details>
<summary>クリックして詳細を表示する</summary>
<p>ここに詳細の内容が表示されます。</p>
</details>コピーボタンコピーチェックボタン

すると、見出しとなる<summary>以外の箇所は折りたたまれた状態となり、以下のように表示されます。

実際の表示

クリックして詳細を表示する

ここに詳細の内容が表示されます。

この<summary>の箇所をクリックするごとに、詳細が開いたり、閉じたりする仕様となっています。クリックできる箇所は三角のアイコン▶だけでなく、文言も含めた<summary>全体になります。

ちなみに、この三角アイコンはブラウザが内部的に描画する「ディスクロージャー・トライアングル」のアイコンのため、Unicodeには存在せず、このページ上では表示できません。そのため、ここでは疑似的に▶(U+25B6)を使って表現しています。

クリックされた<details>項目以外を自動で閉じる方法

上記の場合、クリックされた箇所は、再度クリックするまで自動的には閉じないため、クリックするごとに全て開いてしまい、見えづらくなってしまいます。

そのような場合、以下のように複数の<details>に同じname属性を設定してグループ化することで、クリックした開閉ボタン以外は自動的に閉じるようになります。

<details name="example">
<summary>クリックして詳細を表示する</summary>
<p>ここに詳細の内容が表示されます。</p>
</details>

<details name="example">
<summary>クリックして詳細を表示する</summary>
<p>ここに詳細の内容が表示されます。</p>
</details>

<details name="example">
<summary>クリックして詳細を表示する</summary>
<p>ここに詳細の内容が表示されます。</p>
</details>

実際の表示

クリックして詳細を表示する

ここに詳細の内容が表示されます。

クリックして詳細を表示する

ここに詳細の内容が表示されます。

クリックして詳細を表示する

ここに詳細の内容が表示されます。

これは単純に、同じname属性を持つ<details>であれば、そのページ内のどこにあっても排他的に一つだけ開くように動作します。そのため、<details>と<details>の間に<p>タグなどが入っていても関係なく動作します。

CSSで<summary>開閉ボタンをカスタマイズする方法

この<summary>の開閉ボタンについて、ブラウザのデフォルトでは「三角のアイコン▶」になっていますが、これをクリック可能なボタンとして認識しているユーザーは少ないと感じています。

そのため、この開閉ボタンの表示については、CSSで分かりやすく表示を工夫しておくことをおすすめします。

具体的なカスタマイズ方法としては、まずはCSSでデフォルトの「▶」の表示を無効にした上で、「→」や「+」、「❯」などに変更します。

当サイトの特殊文字・特殊記号の一覧の最下部にある「句読点」の箇所に、「❯」などのリストがありますが、ここでは「U+276F」を使用しています。

ボタンのコードポイント

加えて、色を変更したり、「cursor: pointer;」なども設定した上で、<summary>がクリック可能であることを分かりやすく表示することをおすすめします。

以下はその手順となりますが、まずはCSSで以下のように指定して三角アイコン▶を非表示にします。

summary {
list-style: none;
}
summary::-webkit-details-marker {
display: none;
}
summary::marker {
content: "";
}

実際の表示

クリックして詳細を表示する

ここに詳細の内容が表示されます。


次に、<summary>がクリック可能であることを分かりやすくするため、カーソルをポインターに変更した上で青色の太字にします。

summary {
cursor: pointer;
font-weight: bold;
color: #03C;
}
summary:hover {
background: #eee;
}

実際の表示

クリックして詳細を表示する

ここに詳細の内容が表示されます。


次に、summaryの開始位置を後ろにずらした上で、非表示にした「▶」の代わりに、「❯」をrotateで90度回転させて下向きで表示します。

summary {
position: relative;
padding: 8px 12px 8px 32px;
}
summary::before {
content: "❯";
position: absolute;
top: 8px;
left: 12px;
transform: rotate(90deg);
}

実際の表示

クリックして詳細を表示する

ここに詳細の内容が表示されます。


さらに、クリックして詳細を開いた際に、アイコンが反転するようにします。いわゆるtoggle button(トグルボタン)と呼ばれるものになりますが、toggleは「切り替え」の意味で、開閉や表示・非表示を切り替えるものになります。

このトグルボタンをクリックした際、ブラウザ側で自動的にopen属性が付与されるため、details[open]を設定することで開いた状態のCSSを指定できます。つまり、details[open]は「open属性を持つdetails」の意味になります。

ただ、アイコンが反転した際に位置がずれるかと思いますが、これはフォントのグリフによって中心が異なることが原因のため、調整は難しいです。

topとleftを目視で微調整するしかないと思いますが、キャプチャー画像で拡大するなどして調整することをおすすめします。

トグルボタンの位置調整

details[open] summary::before {
left: 11px;
transform: rotate(-90deg);
}

実際の表示

クリックして詳細を表示する

ここに詳細の内容が表示されます。


どうしても位置がずれる場合には、少し面倒ではありますが、SVG画像で設定することもおすすめします。

その他、外枠なども設定して微調整します。

details {
border-top: #e1e3e1 solid 1px;
border-bottom: 1px solid #e1e3e1;
}

実際の表示

クリックして詳細を表示する

ここに詳細の内容が表示されます。

これらをまとめると以下のようになります。

summary {
list-style: none;
cursor: pointer;
font-weight: bold;
color: #03C;
position: relative;
padding: 8px 12px 8px 32px;
}
summary::-webkit-details-marker {
display: none;
}
summary::marker {
content: "";
}
summary:hover {
background: #eee;
}
summary::before {
content: "❯";
position: absolute;
top: 8px;
left: 12px;
transform: rotate(90deg);
}
details[open] summary::before {
left: 11px;
transform: rotate(-90deg);
}
details {
border-top: #e1e3e1 solid 1px;
border-bottom: 1px solid #e1e3e1;
}コピーボタンコピーチェックボタン

当サイト運営者はSVG画像で設定していますが、「content: "❯";」を上記のように回転させた上で設定すると、ほぼ同じような表示になるかと思います。

SVG画像で開閉ボタンを設定する方法

上記のように、content: "❯";の文字で開閉ボタンを設定した場合、クリックして反転させると位置がずれてしまうため、手動で微調整する必要が出てきてしまいます。また、png画像で設定した場合でも、回転軸の中心がズレていれば、画像編集ソフトなどで微調整する必要がでてきます。

その点、SVG画像のアイコンを使用すれば、回転軸の中心を数値であわせることができるため、反転したアイコンの位置をぴったり合わせることができます。

この手順としましては、まずはGoogle FontsなどでSVG画像のアイコンを用意します。

ちなみに、当サイトで使用しているSVG画像はこちらです。

SVGアイコン

次に、用意したSVG画像の色を指定しますが、メモ帳などで画像ファイルを開き、fill=""を追加して色を指定するとよいでしょう。

<path d="..." fill="#03C" />

このSVG画像をホームページにアップロードし、上記コードのdetails summary::beforeの箇所にて、background-imageの背景画像で設定します。その際、「content: "";」で文字は指定せず、「width、height」で空の領域を確保した上で背景画像として設定します。

details summary::before {
content: "";
position: absolute;
left: 4px;
top: 50%;
width: 24px;
height: 24px;
background-image: url("sample.svg");
background-size: contain;
background-repeat: no-repeat;
transform: translateY(-50%) rotate(0deg);
}

また、「background-size: contain;」を設定して、画像全体をはみ出さないように全て収めます。

加えて、「top:50%;」にて高さを中央に揃えますが、この場合はアイコンの上端が中央に来ることになります。

top:50%;の位置

そのため、translateY(-50%)を設定し、要素の高さ24pxの半分(50%)にて、12px分を上にずらすことで、ぴったり中央に揃えることができます。

これらをまとめると以下のようになります。
(※sample.svgの箇所には任意のSVG画像を設定)

summary {
list-style: none;
cursor: pointer;
font-weight: bold;
color: #03C;
position: relative;
padding: 8px 12px 8px 32px;
}
summary::-webkit-details-marker {
display: none;
}
summary::marker {
content: "";
}
summary:hover {
background: #eee;
}
details summary::before {
content: "";
position: absolute;
left: 4px;top: 50%;
width: 24px;
height: 24px;
background-image: url("sample.svg");
background-size: contain;
background-repeat: no-repeat;
transform: translateY(-50%) rotate(0deg);
}
details[open] summary::before {
transform: translateY(-50%) rotate(-180deg);
}コピーボタンコピーチェックボタン

実際の表示

クリックして詳細を表示する

ここに詳細の内容が表示されます。

反転のrotate(-180deg)については、正の角度が左回りとなるため、rotate(-180deg)で右回りとなります。

また、transformは部分的には継承されず、その全体が上書きされるため、details[open]の箇所にもtranslateY(-50%)は省略せずに書く必要があります。

上記のように、文字でもSVG画像でもほぼ同じように表示されますが、SVG画像の方が数値で指定できるため、設定はしやすいと思います。

JavaScriptの折りたたみ開閉ボタンとの比較

この折り畳み開閉ボタンについては、以前まではJavaScriptにて設定するのが一般的でした。

けれども、JavaScriptを無効にしている環境では機能しませんし、スクリプトを外部化して読み込む場合にはわずかに重くなります。また、検索エンジン対策の面からいっても、上記<details><summary>タグの方がセマンティックな面でメリットがあります。

ただ、より複雑な機能を追加する場合には、やはりJavaScriptを利用した方が便利です。

例えば、自サイトでは詳細が縦長になる箇所はJavaScriptにて開閉ボタンを設置していますが、以下のように「閉じる」ボタンが追従する形で設定することもできます。

追従する閉じるボタン

そのため、<details><summary>タグは、比較的、簡素な内容の際に向いていると感じています。HTMLとCSSのみの方がサクサク動きますし、設置も上記のように簡単なため、複雑な機能が必要ない場合には<details><summary>で設定するとよいでしょう。