I-005 Interaction medium

How to create a accordion アコーディオンの作り方

Accordion that expands and collapses on click. Customize animation speed and styling. クリックで展開/折りたたみができるアコーディオン。アニメーション速度とスタイルをカスタマイズできます。

ライブデモ Live Demo

セクション 1 Section 1
これは最初のセクションのコンテンツです。アコーディオンをクリックすると展開されます。 This is the content for the first section. Click the accordion to expand it.
セクション 2 Section 2
これは2番目のセクションのコンテンツです。複数のセクションを同時に開くことができます。 This is the content for the second section. Multiple sections can be open at the same time.
セクション 3 Section 3
これは3番目のセクションのコンテンツです。FAQや詳細情報の表示に適しています。 This is the content for the third section. Ideal for FAQs and detailed information display.
300ms
30%
10%

概要・用途・特徴Overview, Usage & Features

何ができるかWhat it does

Accordion that expands and collapses on click. Customize animation speed and styling.

クリックで展開/折りたたみができるアコーディオン。アニメーション速度とスタイルをカスタマイズできます。

どこで使うかWhere to use

user engagement, data entry, content management, settings panel

FAQセクション、設定パネル、サイドバーメニュー、コンテンツ管理

特徴Key features

Smooth height animation using CSS grid-template-rows trick (0fr → 1fr) avoiding expensive max-height hacks. Supports single-open or multi-open modes. Keyboard navigable with arrow key support. ARIA attributes (aria-expanded, aria-controls) built in.

CSSのgrid-template-rows(0fr→1fr)トリックで高さアニメーション(max-heightハックを回避)。シングルオープン/マルチオープンモードをサポート。矢印キーサポートでキーボードナビゲーション対応。ARIAアトリビュート(aria-expanded・aria-controls)を組み込み。

調整可能パラメータ Adjustable Parameters

Parameter Default Description
--accordion-durationexpand/collapse animation duration (e.g., 0.3s, 0.5s)
--accordion-bgaccordion background color (e.g., rgba(255, 255, 255, 0.05))
--accordion-borderborder color (e.g., rgba(92, 106, 196, 0.2))
--accordion-easinganimation easing function (e.g., cubic-bezier(0.4, 0, 0.2, 1), ease, linear)
animation toggletoggle animation on/off (disable with `no-animation` class)
icon styleicon style (+, -, ▼, etc.)
single/multipleallow only one open at a time or multiple

実装コード Implementation Code

// react/I-005.jsx
import { useState } from "react";
import "./I-005.css";

export default function Accordion({ 
  title, 
  children,
  duration = "0.3s",
  bgColor = "rgba(255, 255, 255, 0.3)",
  borderColor = "rgba(92, 106, 196, 0.2)",
  easing = "cubic-bezier(0.4, 0, 0.2, 1)",
  noAnimation = false
}) {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div 
      className={`accordion ${isOpen ? "is-open" : ""} ${noAnimation ? "no-animation" : ""}`}
      style={{
        "--accordion-duration": duration,
        "--accordion-bg": bgColor,
        "--accordion-border": borderColor,
        "--accordion-easing": easing
      }}
    >
      <div
        className="accordion__header"
        onClick={() => setIsOpen(!isOpen)}
      >
        {title}
        <span className="accordion__icon"></span>
      </div>
      <div className="accordion__content">
        <div className="accordion__body">
          {children}
        </div>
      </div>
    </div>
  );
}
/* react/I-005.css */
:root {
  --accordion-duration: 0.3s;
  --accordion-bg: rgba(255, 255, 255, 0.3);
  --accordion-border: rgba(92, 106, 196, 0.2);
  --accordion-easing: cubic-bezier(0.4, 0, 0.2, 1);
}

.accordion {
  background: var(--accordion-bg);
  border-radius: 8px;
  padding: 8px 12px;
  margin-bottom: 8px;
  border-bottom: 5px solid var(--accordion-border);
}

.accordion__content {
  max-height: 0;
  overflow: hidden;
  transition: max-height var(--accordion-duration) var(--accordion-easing), padding var(--accordion-duration) var(--accordion-easing);
  padding: 0;
}

.accordion.is-open .accordion__content {
  max-height: 500px;
  padding-bottom: 16px;
}

.accordion.no-animation .accordion__content {
  transition: none;
}

.accordion__icon {
  transition: transform var(--accordion-duration) var(--accordion-easing);
}

.accordion.is-open .accordion__icon {
  transform: rotate(45deg);
}

.accordion.no-animation .accordion__icon {
  transition: none;
}
import { useState } from "react";
import "./I-005.css";

export default function Accordion({
  title,
  children,
  duration = "0.3s",
  bgColor = "rgba(255, 255, 255, 0.3)",
  borderColor = "rgba(92, 106, 196, 0.2)",
  easing = "cubic-bezier(0.4, 0, 0.2, 1)",
  noAnimation = false
}) {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div
      className={`accordion ${isOpen ? "is-open" : ""} ${noAnimation ? "no-animation" : ""}`}
      style={{
        "--accordion-duration": duration,
        "--accordion-bg": bgColor,
        "--accordion-border": borderColor,
        "--accordion-easing": easing
      }}
    >
      <div
        className="accordion__header"
        onClick={() => setIsOpen(!isOpen)}
      >
        {title}
        <span className="accordion__icon"></span>
      </div>
      <div className="accordion__content">
        <div className="accordion__body">
          {children}
        </div>
      </div>
    </div>
  );
}
:root {
  --accordion-duration: 0.3s;
  --accordion-bg: rgba(255, 255, 255, 0.3);
  --accordion-border: rgba(92, 106, 196, 0.2);
  --accordion-easing: cubic-bezier(0.4, 0, 0.2, 1);
}

.accordion {
  background: var(--accordion-bg);
  border-radius: 8px;
  padding: 8px 12px;
  margin-bottom: 8px;
  border-bottom: 5px solid var(--accordion-border);
}

.accordion__header {
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.accordion__content {
  max-height: 0;
  overflow: hidden;
  transition: max-height var(--accordion-duration) var(--accordion-easing), padding var(--accordion-duration) var(--accordion-easing);
  padding: 0;
}

.accordion.is-open .accordion__content {
  max-height: 500px;
  padding-bottom: 16px;
}

.accordion.no-animation .accordion__content {
  transition: none;
}

.accordion__icon {
  transition: transform var(--accordion-duration) var(--accordion-easing);
}

.accordion.is-open .accordion__icon {
  transform: rotate(45deg);
}

.accordion.no-animation .accordion__icon {
  transition: none;
}

仕組みとカスタマイズHow It Works & Customization

仕組みHow it works

Each accordion item has a trigger button and a content wrapper. The wrapper uses display: grid with grid-template-rows: 0fr. The inner content element has overflow: hidden. Toggling to 1fr causes the grid to animate to the content's natural height — no fixed max-height needed. JavaScript manages ARIA states and optionally closes sibling items.

各アコーディオンアイテムはトリガーボタンとコンテンツラッパーを持ちます。ラッパーはgrid-template-rows:0frのdisplay:gridを使用。内部コンテンツ要素にはoverflow:hiddenを設定。1frに切り替えることでグリッドがコンテンツの自然な高さにアニメーション — 固定max-heightが不要。JavaScriptがARIA状態を管理し、オプションで兄弟アイテムを閉じます。

カスタマイズ方法Customization

Set --accordion-duration to control animation speed. Use --accordion-easing for a bounce or spring feel. Add an icon that rotates 180° on open (via CSS transition). For nested accordions, apply the same class recursively.

--accordion-durationでアニメーション速度を制御。--accordion-easingでバウンスやスプリングの感触に。オープン時に180°回転するアイコンを追加(CSSトランジションで)。ネストされたアコーディオンには同じクラスを再帰的に適用。

注意点Caveats

The grid-template-rows trick requires the direct child to have overflow: hidden — do not add padding to the content wrapper directly (add it to an inner element). Test keyboard navigation to ensure Tab moves into open panels and Escape closes them per ARIA Authoring Practices.

grid-template-rowsのトリックでは直接の子要素にoverflow:hiddenが必要です。コンテンツラッパーに直接パディングを追加しないでください(内部要素に追加してください)。ARIAオーサリングプラクティスに従ってTabがオープンパネルに移動し、Escapeが閉じることをキーボードナビゲーションでテストしてください。

よくある質問 Frequently Asked Questions

How to customize the accordion? Accordionをカスタマイズするには?

Modify the CSS custom properties and class styles defined in the code section. Key adjustable values include colors, sizes, durations, and spacing. See the Adjustable Parameters section for specific variables.

コードセクションで定義されているCSSカスタムプロパティとクラススタイルを変更してください。色、サイズ、時間、間隔が主な調整可能値です。具体的な変数は調整可能パラメータセクションを参照してください。

How to use the accordion in React? ReactでAccordionを使うには?

Import the provided React component and its CSS file. The component accepts props for customization. Check the React code section for the full implementation and available props.

提供されているReactコンポーネントとCSSファイルをインポートしてください。コンポーネントのpropsでカスタマイズできます。完全な実装と利用可能なpropsはReactコードセクションを参照してください。

What are the performance implications of accordion? Accordionのパフォーマンスへの影響は?

This implementation uses CSS transforms and opacity for animations, which are GPU-accelerated. It's lightweight and doesn't cause layout thrashing. Consider using prefers-reduced-motion for accessibility.

この実装はCSSのtransformとopacityを使用しており、GPUアクセラレーションされます。軽量でレイアウトスラッシングを引き起こしません。アクセシビリティのためにprefers-reduced-motionの使用を検討してください。

AIへの指示テンプレート AI Prompt Template

以下をAIに貼り付けると実装を依頼できます。 Paste the following into your AI assistant to request implementation.