アコーディオンの動きをCSSで作ってみた

jQueryだとアコーディオンって簡単に作れるな、という印象だったのですが
今回はアコーディオンの開閉切り替えのみをJavaScriptで、アニメーションはCSSのみで作ってみました。

## HTML
```accordion.html
<button class="trigger" aria-controls="accordion" aria-expanded="false" data-button="accordion">Accordion</button>
<div id="accordion" class="accordion_contents" aria-hidden="true">
  <h2 class="accordion__title">アコーディオンの中身</h2>
  <p class="accordion__text">テキストテキストテキストテキストテキストテキスト</p>
  <p class="accordion__text">テキストテキストテキストテキストテキストテキスト</p>
  <p class="accordion__text">テキストテキストテキストテキストテキストテキスト</p>
  <p class="accordion__text">テキストテキストテキストテキストテキストテキスト</p>
  <p class="accordion__text">テキストテキストテキストテキストテキストテキスト</p>
</div>
```

## CSS
```style.scss
.trigger {
  position: relative;
  width: 100%;
  padding: 20px 40px;
  background-color: #f85c82;
  border: none;
  transition: .4s;

  &:hover {
    cursor: pointer;
    opacity: 0.6;
    transition: .4s;
  }

  &[aria-expanded="false"] {
    border-radius: 15px;
  }

  &[aria-expanded="true"] {
    border-radius: 15px 15px 0 0;
  }
}

.accordion {

  &_contents {
    font-size: 18px;
    background-color: #fff;
    border-right: 2px solid #f85c82;
    border-bottom: 2px solid #f85c82;
    border-left: 2px solid #f85c82;
    border-radius: 0 0 15px 15px;

    &[aria-hidden="true"] {
      height: 0;
      padding: 0 40px;
      overflow: hidden;
      visibility: hidden;
      opacity: 0;
      transition: .5s;
    }

    &[aria-hidden="false"] {
      height: auto;
      min-height: 100px;
      padding: 40px;
      visibility: visible;
      opacity: 1;
      transition: .5s;
    }
  }

  &__title {
    margin: 0 0 40px 0;
    font-size: 25px;
  }

  p {
    & + p {
      margin-top: 20px;
    }
  }
}
```
アコーディオンclose時、上下のpaddingを設定するとpadding分の空間があいてしまうため0pxに設定しています。
かといって全てのpaddingを0にしてしまうと、open時にtransition分の時間をかけてテキストが動いてしまうため、左右のpaddingのみ設定するようにしてみました。

## JavaScript
```accordion.js
function accordion() {
  const controlButton = document.querySelectorAll('[data-button="accordion"]');

  const contents = document.getElementById('accordion');

  for (let i = 0; i < controlButton.length; i += 1) {
    controlButton[i].addEventListener('click', () => {
      if (contents.getAttribute('aria-hidden') === 'true') {
        contents.setAttribute('aria-hidden', 'false');
        controlButton[i].setAttribute('aria-expanded', 'true');
      } else if (contents.getAttribute('aria-hidden') === 'false') {
        contents.setAttribute('aria-hidden', 'true');
        controlButton[i].setAttribute('aria-expanded', 'false');
      }
    });
  }
}
accordion();
```
今回JSはアコーディオンのopen、closeの状態管理だけです。

## デモ
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="gOoJBWE" data-user="Rinux_is_a_Pen" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/Rinux_is_a_Pen/pen/gOoJBWE">
  Accordion</a> by Akane Kanesaka (<a href="https://codepen.io/Rinux_is_a_Pen">@Rinux_is_a_Pen</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 感想
もう少し開閉のアニメーションを滑らかにできたらなぁ、と思いました。
折り畳んでる感があまりないので、CSS animationを使って改善していきたいです。