コピペで完結!アコーディオン#04【単一オープン(他自動クローズ)】

html/css/js

一つ開くと他が閉じるタイプ(ラジオ連動)

複数のアコーディオン項目のうち、常に一つだけ開くタイプです。
新しい項目を開くと、他の項目は自動的に閉じるようになっています。
JavaScriptで制御し、FAQなどで情報を整理して見せたい場面に最適です。

コードについて 本記事のコードは AI(ChatGPT)による生成をベースに作成・調整しています。ご利用の環境でテストの上ご使用ください。
免責 本コードの利用に伴う不具合・損害について、当サイトは責任を負いません。自己責任にてご利用ください。

デモ

はい。一つ開くと他の項目は自動的に閉じます。
スライドとフェードを組み合わせた自然な開閉アニメーションです。
このサンプルはJavaScript制御版のため、JSが必要です。

コードをコピーして使おう!

/* =========================================================
   ▼CSS:単一オープン(他自動クローズ)アコーディオン
   目的:
     - 「一つ開くと他が閉じる」UIを想定した見た目を定義
     - 高さアニメーション用の土台(.panel / .panel-inner)を整える
     - 矢印アイコンの回転(aria-expanded と連動)を表現
   スコープ:
     - #accordion-section 内で完結(他スタイルと衝突しない)
   ========================================================= */

/* ========== コンテナ(アコーディオン全体) ========== */
#accordion-section{
  border:1px solid #e5e7eb;       /* 全体の枠線:薄いグレーでカード感を出す */
  border-radius:10px;             /* カードの角丸:柔らかい印象にする */
  background:#fff;                /* ベース背景:本文の視認性を確保 */
  overflow:hidden;                /* 子要素の角丸はみ出しやアニメ中のズレを抑止 */
}

/* ========== 各項目(item) ========== */
#accordion-section .item{
  border-bottom:1px solid #e5e7eb;/* 各項目の区切り線:視認性・可読性の向上 */
  /* 最後の項目の下線は必要に応じて :last-child で外してもよい */
}

/* ========== タイトル(アクセシブル見出しラッパー) ========== */
#accordion-section .accordion-title{
  margin:0;                       /* デフォルト余白をリセット(レイアウトのズレ防止) */
  /* h3タグは不使用。role="heading" aria-level="3" で見出しレベルを補完 */
}

/* ========== トグルボタン(クリックで開閉) ========== */
#accordion-section .toggle{
  display:flex;                   /* テキストとアイコンを横並びにする */
  align-items:center;             /* アイコンとテキストを縦方向中央揃え */
  justify-content:space-between;  /* 左にテキスト/右にアイコンを配置 */
  width:100%;                     /* 横幅いっぱいクリック可能にする */
  padding:14px 16px;              /* クリックしやすい余白(タップ目安44pxを考慮) */
  border:none;                    /* 既定ボーダーを除去(フラットな見た目に) */
  background:#f8fafc;             /* 淡いグレー背景:ボタン領域を識別しやすく */
  cursor:pointer;                 /* ホバー時にポインタでクリック可能を示す */
  font-weight:600;                /* タイトルらしく少し強めのウエイト */
  text-align:left;                /* ボタン内テキストを左寄せ */
  transition:background .25s;     /* ホバー背景の変化をなめらかに */
  /* キーボード操作のフォーカス可視化は :focus-visible で上位CSSに追加可 */
}

/* ホバー時:背景色を少し青みのある淡色にしてアフォーダンスを出す */
#accordion-section .toggle:hover{
  background:#eef2ff;             /* 反応がわかりやすい微差色 */
}

/* ========== 矢印アイコン(回転アニメーション対象) ========== */
#accordion-section .icon{
  transition:transform .3s;       /* 回転アニメーションの時間を定義 */
  /* 初期状態は ▼(下向き)を想定。開いたら上向きへ反転させる */
}

/* ボタン状態が "開" のとき:矢印を180度回転(▼→▲) */
#accordion-section .toggle[aria-expanded="true"] .icon{
  transform:rotate(180deg);       /* 開状態を視覚的に伝える */
}

/* ========== パネル(スライドアニメの外枠) ========== */
#accordion-section .panel{
  overflow:hidden;                /* スライド中の内容はみ出しを隠す */
  height:0;                       /* 初期状態は閉じる(0px) */
  transition:height .28s ease;    /* 高さの変化でスライド感を演出 */
  /* height は JS で 0px → 実測px → auto と遷移させる(安定動作のため) */
}

/* ========== パネル内側(実コンテンツ/フェード演出) ========== */
#accordion-section .panel-inner{
  padding:16px;                   /* コンテンツ内側の余白 */
  line-height:1.8;                /* 読みやすい行間 */
  background:#fff;                /* 本文背景:親と同一で一体感 */
  opacity:0;                      /* 初期は非表示(フェードのため) */
  transform:translateY(-2px);     /* ほんの少し上から出現させる演出 */
  transition:opacity .25s,        /* フェードインの滑らかさ */
             transform .25s;      /* スライド量の変化を同期 */
}

/* パネルが開いた状態(data-open="true")で内側をフェードイン */
#accordion-section .panel[data-open="true"] .panel-inner{
  opacity:1;                      /* 完全に表示 */
  transform:translateY(0);        /* 元の位置に戻す */
}

/* ========== 動きを控えるユーザー設定への配慮(任意だが推奨) ========== */
/* OS設定で「簡易動作」を選択しているユーザーにはアニメーションを抑制 */
@media (prefers-reduced-motion: reduce){
  #accordion-section .icon{
    transition:none;              /* 矢印回転を瞬時に */
  }
  #accordion-section .panel{
    transition:none;              /* 高さアニメーションを無効化 */
  }
  #accordion-section .panel-inner{
    transition:none;              /* フェード/スライドを無効化 */
    opacity:1;                    /* すぐに表示 */
    transform:none;               /* 位置も即時反映 */
  }
}

コメント