CSSのみでアコーディオンを実現!detailsとsummaryについて


jsを駆使してアコーディオンを作るたびに思います。
「毎回めんどくさい…もっと秒でやりたい…」
そんな悩みを解決してくれる要素について記事にしました。

使用方法

See the Pen HowToUseDetails&Summary by shake (@mgmgshake) on CodePen.

とっても簡単ですよね!
jsいらずで、HTMLのみでアコーディオンが実装できます♪
また、スタイルを上書きできるので自分好みのアコーディオンにすることもできます。

対応するブラウザ

便利なdetail&summaryですが、対応するブラウザは以下のようになっております。


引用元:https://developer.mozilla.org/ja/docs/Web/HTML/Element/details

…まぁ、いつも通りですね!

chrome,Firefox,safariでは普通に動くが、癖があります。(後述)
IE, Edgeはpolyfillを入れることにより使用可能になります。

↓Edgeで見た状態

使用したpolyfill

details-element-polyfillを使用しました。

結構種類が豊富であり、4個ほどpolyfillを試したのですがまともに動作したのが2つだけでした…。
→シンプルなHTML構造ではないと使えない可能性あり?

ブラウザごとのクセ

デフォルトでついているアイコンを削除する必要があります。
そのアイコンが、ブラウザによって扱いが異なります。

ブラウザ 状態 削除方法
chorome details-markerという特殊な擬似要素 summary::-webkit-details-marker { display: none; }
safari 上と同じ 上と同じ
firefox list-itemなのでlist-style扱い list-style none あるいはlist-style-image設定
IE,Edge 擬似要素(before) ::before content ''

※IE, Edgeはpolyfillにより異なる

firefoxのみ無駄にlist-styleのため、summaryにdisplay: blockをかけるとその瞬間にアイコンが消えます。ちょっと不便。
少し面倒くさいですが、list-styleを消してしまって擬似要素で共通のアイコンを設定したが早いです。

Vue.jsとの共存

条件によってアコーディオンの初期状態を制御したいとき、
detailsにはopenという独自の属性があるので、そちらをv-bindします

<details v-bind:open="closeOption ? false : 'open' ">
    <summary>まぐろ</summary>
    ビチビチ
</details>

closeOptionがtrue→open=falseになる

html
 // 閉じられる(普通のアコーディオン)
<details>
    <summary>まぐろ</summary>
    ビチビチ
</details>

false→open=openになる

html
// 最初から開かれる
<details open="open">
    <summary>まぐろ</summary>
    ビチビチ
</details>

扱いにくい点

開いたら開きっぱなしにしたいときや、ユーザの状態によってアコーディオンそのものを無くしたいときなどがあると思います。

例えば、アンケートページでの任意項目はアコーディオンにして隠して置いて、ユーザが開いたら出しっぱなしにしたい時などです。
(あくまで例なので、details&summaryじゃなくてv-if使えば?というご意見はなしで…!)

summaryにv-if効かない問題

html
// 最初から開かれる
<details open="open">
    <summary v-if="false">まぐろ</summary>
    ビチビチ
</details>


↑openDetail=falseのとき、summaryは消えずに「詳細」という内容に置き換わるだけ

v-ifでsummaryを消すと、勝手にどこかでsummaryが生成されてしまいます
CSSをあてることもできません
→どうやらsummaryのDOMがないと無理やりどこかで付け加える仕様のようです

detailsがopenのときに、summaryをdisplay noneにする記述を書けば解決することができます。

details[open]
    summary
        display none

所感

まだまだ制約が多いので、デザインやアニメーションなどを凝りたい時は従来のアコーディオンの生成方法で良い気がしますが、
時間がなくてちゃちゃっと実装したい時にはいいかもしれません。

新しめのhtmlタグってなかなか触れる機会がなくて困ります…。