アコーディオン
アコーディオン
ここはアコーディオンの中身です。高さが自動で計算されるので、文章量が変わってもアニメーションがスムーズに動作します。
AstroとMicroCMSを使用しています。まずはGitHubからリポジトリをクローンし、npm installを実行してください。
<div class="demo-accordion">
<!-- 1つ目のアイテム -->
<div class="acc-item">
<button class="acc-btn">
<span>よくある質問その1</span>
<span class="acc-icon"></span>
</button>
<div class="acc-content">
<div class="acc-inner">
<p>ここはアコーディオンの中身です。高さが自動で計算されるので、文章量が変わってもアニメーションがスムーズに動作します。</p>
</div>
</div>
</div>
<!-- 2つ目のアイテム -->
<div class="acc-item">
<button class="acc-btn">
<span>開発環境の構築方法は?</span>
<span class="acc-icon"></span>
</button>
<div class="acc-content">
<div class="acc-inner">
<p>AstroとMicroCMSを使用しています。まずはGitHubからリポジトリをクローンし、npm installを実行してください。</p>
</div>
</div>
</div>
</div> /* アコーディオン全体 */
.demo-accordion {
border: 1px solid #e2e8f0;
border-radius: 8px;
overflow: hidden;
background: #fff;
}
/* アイテムごとの枠線 */
.acc-item {
border-bottom: 1px solid #e2e8f0;
}
.acc-item:last-child {
border-bottom: none;
}
/* ボタン(ヘッダー) */
.acc-btn {
width: 100%;
padding: 16px 20px;
background: #f8fafc;
border: none;
text-align: left;
font-weight: bold;
font-size: 16px;
color: #334155;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
transition: background 0.2s;
}
.acc-btn:hover {
background: #f1f5f9;
}
/* 中身エリア(初期は高さ0) */
.acc-content {
height: 0;
overflow: hidden;
transition: height 0.3s ease-out;
background: #fff;
}
/* 中身の余白 */
.acc-inner {
padding: 20px;
line-height: 1.6;
color: #475569;
}
/* アイコン(+マーク) */
.acc-icon {
position: relative;
width: 16px;
height: 16px;
}
.acc-icon::before,
.acc-icon::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
background: #64748b;
transform: translate(-50%, -50%);
transition: transform 0.3s;
}
.acc-icon::before { width: 100%; height: 2px; }
.acc-icon::after { width: 2px; height: 100%; }
/* 開いた状態のデザイン */
.acc-item.is-active .acc-icon::after {
transform: translate(-50%, -50%) rotate(90deg); /* +が回転してーになる */
} // 全てのアコーディオンアイテムを取得
const items = document.querySelectorAll('.acc-item');
items.forEach(item => {
const btn = item.querySelector('.acc-btn');
const content = item.querySelector('.acc-content');
btn.addEventListener('click', () => {
// 現在の状態を取得
const isOpen = item.classList.contains('is-active');
// 開閉処理
if (isOpen) {
// 閉じる
item.classList.remove('is-active');
content.style.height = '0';
} else {
// 開く(高さを内部の高さに合わせて設定)
item.classList.add('is-active');
content.style.height = content.scrollHeight + 'px';
}
});
});