0
Help us understand the problem. What are the problem?
Organization

アコーディオンの動きを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の状態管理だけです。

デモ

See the Pen Accordion by Akane Kanesaka (@Rinux_is_a_Pen) on CodePen.

感想

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

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
0
Help us understand the problem. What are the problem?