JSなしで、アコーディオンを実装

完成品

See the Pen Untitled by yokosawa (@yokosawa) on CodePen.



コードの解説

HTML

記述すべき、HTMLは非常にシンプルです。

<details class="faq__item">

  <!-- 最初に表示しておく文字列 -->
  <summary class="faq__title">質問文</summary>

  <!-- 開いた時に表示したい文字列 -->
  <p class="faq__detail">回答文</p>

</details>

summaryタグの要素をクリックすると、detailsタグにopen属性が付与され、アコーディオンが開きます。
再度クリックすると、detailsタグからopen属性が削除され、アコーディオンが閉じます。
この挙動をさせるためのJavaScriptの記述は一切しておらず、detailsタグがデフォルトでこのような挙動をします。

また、CODEPENに記載している1番下のアコーディオンは元々開かれている状態ですが、これはdetailsタグにopen属性をはじめから記述しているからです。


CSS

※特殊な記述等にはコメントアウトで説明を記載しています。

.wrap {
  max-width: 1000px;
  padding: 0 20px;
  margin: 0 auto;
}

.faq__item {
  padding: 20px;
  border: 1px solid #000;
}

/* 最後の.faq__item以外に、margin-bottom: 20px;を指定 */
.faq__item:not(:last-child) {
  margin-bottom: 20px;
}

.faq__title {
  padding-right: 20px;
  font-size: 20px;
  font-weight: 700;
  display: block;
  position: relative;
  cursor: pointer;
}

/* Safariだと、先頭に自動的に三角が表示されるので、非表示にする記述 */
.faq__title::-webkit-details-marker {
  display: none;
}

.faq__title::before {
  content: "Q.";
  margin-right: 5px;
  font-size: 20px;
  font-weight: 700;
}

/* 質問文右に表示する三角形 */
.faq__title::after {
  content: "";
  width: 15px;
  aspect-ratio: 1/cos(30deg);
  top: 50%;
  right: 0;
  background-color: #000;
  clip-path: polygon(0 0, 100% 0%, 50% 100%);
  position: absolute;
  translate: 0 -50%;
  transition: all .3s;
}

/* 開いた時に、三角形を180度回転 */
.faq__item[open] .faq__title::after {
  rotate: 180deg;
}

.faq__detail {
  padding: 10px 0;
  font-size: 16px;
  font-weight: 500;
}

detailsタグとsummaryタグで実装するメリット

上記HTMLの記述のみで、アクセシビリティに最適化されています。

  • tabキー、エンターキーで開閉操作可能
  • スクリーンリーダー(読み上げ機能)で開閉状態まで読み上げてもらえる

今までだと、divタグなどで実装していたかと思いますが、上記メリットに記述したことを再現しようとすると、tabindex属性の記述やJavaScriptの記述をしなくてはいけません。

学習コストもかからないので、ぜひ積極的に採用してみてください!



参考記事

https://ics.media/entry/220901