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を入れることにより使用可能になります。
使用した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になる
// 閉じられる(普通のアコーディオン)
<details>
<summary>まぐろ</summary>
ビチビチ
</details>
false→open=openになる
// 最初から開かれる
<details open="open">
<summary>まぐろ</summary>
ビチビチ
</details>
扱いにくい点
開いたら開きっぱなしにしたいときや、ユーザの状態によってアコーディオンそのものを無くしたいときなどがあると思います。
例えば、アンケートページでの任意項目はアコーディオンにして隠して置いて、ユーザが開いたら出しっぱなしにしたい時などです。
(あくまで例なので、details&summaryじゃなくてv-if使えば?というご意見はなしで…!)
summaryにv-if効かない問題
// 最初から開かれる
<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タグってなかなか触れる機会がなくて困ります…。