JavaScript不要!アコーディオンの作り方
上記のようなアコーディオンを作ろうとしてGoogleで検索をすると、<div>
や<input>
を使ったものが多く見つかります。
div
やinput
を使うと、セットでJavaScriptを使わなければならない…JavaScripがあまり得意ではない・時間をあまりかけたくないと思う方も多いのではないでしょうか。
しかし<details>
と<summary>
を使うと、簡単&以下のメリットがあります。
- アクセシビリティ対策になる
- 構造がわかりやすい、読みやすいコードになる
- JavaScript不要で開閉ができる
今回は<details>
と<summary>
タグを使って、JavaScript不要でアコーディオンを作る方法を紹介します。
HTMLとCSS
結論のHTMLとCSSです。
下の方で詳細に解説をします。
HTMLはリセットCSSを読み込んで使用すると、崩れがないです。
<details>
<summary class="summary">
<div class="summary__inner">
<p class="summary__text">
質問のテキスト質問のテキスト<br />質問のテキスト質問のテキスト
</p>
<span class="summary__arrow"></span>
</div>
</summary>
<div class="answer">
<div class="answer__inner">
<p class="answer__text">回答のテキスト回答のテキスト<br>回答のテキスト回答のテキスト</p>
</div>
</div>
</details>
/* 見やすくする用 */
details{
max-width: 840px;
margin: 0 auto;
}
/* Qのテキスト */
.summary {
position: relative;
display: block;
background-color: #f5f5f5;
cursor: pointer;
}
.summary__inner{
padding: 30px;
}
.summary__text{
margin-left: 40px;
}
/* Aのテキスト */
.answer{
position: relative;
display: block;
background-color: #f5f5f5;
cursor: pointer;
}
.answer__inner{
padding: 30px;
}
.answer__text{
margin-left: 40px;
}
/* 装飾用 */
/* iOSで表示されるデフォルトの三角形アイコン削除用 */
.summary::-webkit-details-marker {
display: none;
}
.summary::before{
content: "Q";
position: absolute;
top: 50%;
left: 4%;
transform: translateY(-50%);
width: 30px;
height: 30px;
color: #ffffff;
background-color: skyblue;
border-radius: 50%;
line-height: 30px;
text-align: center;
font-weight: bold;
}
.answer::before{
content: "A";
position: absolute;
top: 50%;
left: 4%;
transform: translateY(-50%);
width: 30px;
height: 30px;
color: #ffffff;
background-color: pink;
border-radius: 50%;
line-height: 30px;
text-align: center;
font-weight: bold;
}
/* 質問文右の矢印 */
.summary__arrow{
position: absolute;
top: 0;
right: 30px;
bottom: 0;
display: block;
height: 15px;
margin: auto;
background-color: #333333;
aspect-ratio: 1/cos(30deg);
clip-path: polygon(100% 13%, 50% 80%, 0 13%, 5% 0, 50% 60%, 95% 0);
transition: 0.4s;
}
/* 質問が開かれたら矢印を回転 */
details[open] .summary .summary__arrow{
transform: rotate(180deg);
}
HTML
details
タグの中に、summary
があれば最低限の動きは再現できます。
CSSもJavaScriptも書かなくても、矢印マークと開閉が自動でつきます。
<details>
<summary>質問です</summary>
回答です
</details>
サンプルでは、装飾のためにclass
を追加しています。また、開閉を示すアイコンとしてsummary__arrow
も置きました。
擬似要素で矢印を再現すればいいのに!と思いますがこれには理由があるのでCSSのほうで解説します。
CSS
背景色をつけたり、質問・回答文の先頭に丸いアイコンをつけたりしています。
さらに、質問文の末尾には矢印アイコンをつけました。
/* 質問文右の矢印 */
.summary__arrow{
position: absolute;
top: 0;
right: 30px;
bottom: 0;
display: block;
height: 15px;
margin: auto;
background-color: #333333;
aspect-ratio: 1/cos(30deg);
clip-path: polygon(100% 13%, 50% 80%, 0 13%, 5% 0, 50% 60%, 95% 0);
transition: 0.4s;
}
/* 質問が開かれたら矢印を回転 */
details[open] .summary .summary__arrow{
transform: rotate(180deg);
}
これは、開いたら矢印を回転させたいためです。
擬似要素で矢印を作らなかった理由は、iOSの場合transitionが効かないためです。
ほかにもiOS用にデフォルトの三角形アイコンを削除するCSSを入れています。
/* iOSで表示されるデフォルトの三角形アイコン削除用 */
.summary::-webkit-details-marker {
display: none;
}
ちなみに、これを入れないとこのように三角形が表示されてしまいます!!
まとめ
CSS・JavaScript不要で簡単にアコーディオンを作成できました。
今回、矢印を作るのに使ったclip-path
について、別の記事で後日まとめます。
今まで三角形を作る時はborder
を使っていたのですが、 clip-path
を使うととても簡単に矢印を作れました!!
Discussion