How to create a accordion アコーディオンの作り方
Accordion that expands and collapses on click. Customize animation speed and styling. クリックで展開/折りたたみができるアコーディオン。アニメーション速度とスタイルをカスタマイズできます。
ライブデモ Live Demo
概要・用途・特徴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-duration | — | expand/collapse animation duration (e.g., 0.3s, 0.5s) |
--accordion-bg | — | accordion background color (e.g., rgba(255, 255, 255, 0.05)) |
--accordion-border | — | border color (e.g., rgba(92, 106, 196, 0.2)) |
--accordion-easing | — | animation easing function (e.g., cubic-bezier(0.4, 0, 0.2, 1), ease, linear) |
animation toggle | — | toggle animation on/off (disable with `no-animation` class) |
icon style | — | icon style (+, -, ▼, etc.) |
single/multiple | — | allow 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.