ミギムキ

[CSS] アコーディオン形式のQ&AリストをCSSで作りたい(for属性不使用)

よくある質問コンテンツ

以前、こちらの記事で紹介したQ&Aリストに少し手を加えました。

labelにfor属性を使わないようにして項目を増やしやすくした他、回答部分にリンクなどのクリック要素を置けるようにしています。

動作イメージ

質問をクリックすると回答がスライドして表示されます。

サンプルコード

html

<dl class="list_qaa"> <label> <input type="checkbox"> <dt>質問1</dt> <label for="dummy"> <dd>回答1</dd> </label> </label> <label> <input type="checkbox"> <dt>質問2</dt> <label for="dummy"> <dd>回答2</dd> </label> </label> <label> <input type="checkbox"> <dt>質問3</dt> <label for="dummy"> <dd>回答3</dd> </label> </label> </dl>

CSS

.list_qaa > label { display: block; position: relative; width: 100%; padding: 0px; margin: 0px; cursor: pointer; } .list_qaa > label > input { display: none; } .list_qaa > label > dt, .list_qaa > label > label > dd { position: relative; padding: 1em 1em 1em 3.5em; font-size: 15px; border-bottom: 1px solid currentColor; background-color: #fff; } .list_qaa > label > dt::before, .list_qaa > label > label > dd::before { position: absolute; top: 50%; left: 0.5em; transform: translateY(-50%); font-size: 2em; } .list_qaa > label > dt { z-index: 1; } .list_qaa > label > dt::before { content: "Q"; } .list_qaa > label > label > dd::before { content: "A"; } .list_qaa > label > dt::after { display: inline-block; position: relative; top: 50%; right: -1em; transform: translateY(-50%) rotate(135deg); width: 0.5em; height: 0.5em; border-top: 2px solid #3388dd; border-right: 2px solid #3388dd; content: ""; } .list_qaa > label > label > dd { position: absolute; top: 0px; left: 0px; transform: translateY(-2em); margin: 0px; visibility: hidden; } .list_qaa > label > input:checked ~ label > dd { position: relative; transform: translateY(0px); visibility: visible; transition: 0.5s; }

サンプルコードの解説

回答部分の開閉

.list_qaa > label > label > dd { position: absolute; top: 0px; left: 0px; transform: translateY(-2em); margin: 0px; visibility: hidden; } .list_qaa > label > input:checked ~ label > dd { position: relative; transform: translateY(0px); visibility: visible; transition: 0.5s; }

回答部分の表示/非表示の切り替えを行うスタイルです。

切り替えのフラグは、チェックボックス形式にしたinputタグで行っています。チェックがされたときに「:checked」セレクタが有効になる仕様を利用します。

inputタグ自体は非表示にしていますが、間接セレクタ「~」を使うことで、inputタグと同じ階層にいる要素のスタイルを切り替えることができます。

「:checked」セレクタが有効になったとき、位置(position、transform)と可視状態(visibility)を変えて回答部分を表示しています。

回答部分のクリック制御

<label> <input type="checkbox"> <dt>質問1</dt> <label for="dummy"> <dd>回答1</dd> </label> </label>

質問と回答の1セットはlabelタグでひとまとめにしています。

そのため、質問部分だけではなく回答部分をクリックしたときにもinputタグのチェック状態が切り替わってしまいます。その結果、回答部分にaタグなどのクリック要素があっても押すことができなくなってしまいます。

対策として、回答部分を更にlabelタグでくくり、for属性にダミーのIDを指定しています。こうすることで、回答部分がクリックされても要素が閉じなくなります。

ご質問など受け付けています

記事の中でわかりにくかったところ、もっと知りたかったこと、間違っていることなど、何でもお気軽にご連絡ください。

ご連絡は下記フォームを利用いただくか、ツイッターアカウント@flat8migi宛てでもOKです。