背景
JavaScript を利用せずに HTML と CSS だけでアコーディオン UI を実装する場合、折りたたみ部分の開閉アニメーションをどうするのかが肝になる。
最近では JavaScript を利用しないでアコーディオン UI を実現するために <details> と <summary> を利用するケースもある。ただ、この場合は折りたたみ部分の開閉アニメーションは利用できない。
JavaScript を利用せずに HTML と CSS だけでアコーディオン UI を実装する場合、折りたたみ部分の開閉アニメーションをどうするのかが肝になる。
最近では JavaScript を利用しないでアコーディオン UI を実現するために <details> と <summary> を利用するケースもある。ただ、この場合は折りたたみ部分の開閉アニメーションは利用できない。
HTML と CSS だけで実装する場合、以下のように開閉時にmax-heightを変えてtransitionさせることでアニメーションを実現する方法がある。
.collapse_body {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-in-out;
}
.collapse_control:checked ~ .collapse_body {
max-height: 100vh;
}
https://b.0218.jp/20150301010529.html
max-heightではなく、gridのgrid-template-rowsをアニメーションさせる。
説明用で簡素にしているが、実装は以下の通り。
<div class="Accordion">
<label class="Accordion-header">
<input type="checkbox" hidden />見出し
</label>
<div class="Accordion-content">
<div class="Accordion-content__inner">中身</div>
</div>
</div>
/* 必要なものだけ抜粋 */
.Accordion {
&:has(.Accordion-header input:checked) {
.Accordion-content {
grid-template-rows: 1fr;
}
}
}
.Accordion-content {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.3s ease-in-out;
}
.Accordion-content__inner {
overflow: hidden;
}
大まかに要素の高さを変えてアニメーションさせる手順は下記の通り。
.Accordion-content:display: gridとgrid-template-rowsを0frで指定するtransitionはgrid-template-rowsに対して指定するgrid-template-rowsを1frにする.Accordion-content__inner:overflow: hidden;を指定しておく:has()が使えない場合JavaScript を利用しないため、開閉状態のフラグをinput[type=checkbox]にもたせている。それを CSS で判定する必要があるが、それは:has(.Accordion-header input:checked)というセレクタで実現している。:has()を利用できない環境の場合は、隣接セレクタや子孫セレクタなどを利用する必要がある。
<div class="Accordion">
<label class="Accordion-header" for="AccordionCheck"> 見出し </label>
<input type="checkbox" id="AccordionCheck" class="Accordion-check" hidden />
<div class="Accordion-content">
<div class="Accordion-content__inner">中身</div>
</div>
</div>
.Accordion-check:checked ~ .Accordion-content {
grid-template-rows: 1fr;
}