2026年5月20日
2026年5月20日
WordPressでアコーディオンメニューを実装する方法
はじめに
アコーディオンUIは、クリックで開閉するコンテンツ折りたたみ機能です。FAQページや長いコンテンツの整理に使われます。WordPressでは details / summary タグ(HTML標準)か、JavaScriptで実装できます。
症状・原因
- FAQをアコーディオン形式で表示したい
- クリックで開閉するコンテンツを作りたい
- アニメーション付きのスムーズな開閉を実装したい
- ショートコードでエディタから追加したい
解決手順
ステップ1:HTMLのdetails/summaryで最もシンプルに実装
<!-- テンプレートに直接記述 -->
<details class="accordion-item">
<summary class="accordion-title">質問:WordPressとは何ですか?</summary>
<div class="accordion-content">
<p>WordPressはPHPで作られたオープンソースのCMSです。世界のウェブサイトの約43%で使用されています。</p>
</div>
</details>
/* style.css */
.accordion-item {
border: 1px solid #c3c4c7;
border-radius: 4px;
margin-bottom: 8px;
}
.accordion-title {
padding: 16px 20px;
cursor: pointer;
font-weight: 600;
list-style: none;
display: flex;
align-items: center;
justify-content: space-between;
user-select: none;
}
.accordion-title::after {
content: '+';
font-size: 18px;
color: #2271b1;
transition: transform 0.2s;
}
.accordion-item[open] .accordion-title::after {
transform: rotate(45deg);
}
.accordion-content {
padding: 0 20px 16px;
color: #50575e;
}
ステップ2:スムーズなアニメーション付き(JavaScript版)
// js/accordion.js
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.js-accordion').forEach(function(item) {
const title = item.querySelector('.accordion-title');
const content = item.querySelector('.accordion-content');
if (!title || !content) return;
// 初期状態で高さを0にする
content.style.height = '0';
content.style.overflow = 'hidden';
content.style.transition = 'height 0.3s ease';
title.setAttribute('aria-expanded', 'false');
title.setAttribute('role', 'button');
title.addEventListener('click', function() {
const isOpen = item.classList.contains('is-open');
if (isOpen) {
// 閉じる
content.style.height = content.scrollHeight + 'px';
requestAnimationFrame(function() {
content.style.height = '0';
});
item.classList.remove('is-open');
title.setAttribute('aria-expanded', 'false');
} else {
// 開く
content.style.height = content.scrollHeight + 'px';
item.classList.add('is-open');
title.setAttribute('aria-expanded', 'true');
// アニメーション終了後にhighを自動にする(リサイズ対応)
content.addEventListener('transitionend', function handler() {
if (item.classList.contains('is-open')) {
content.style.height = 'auto';
}
content.removeEventListener('transitionend', handler);
});
}
});
});
});
ステップ3:FAQショートコードとして実装
// functions.php
add_shortcode('faq', function(array $atts, ?string $content = null): string {
return '<div class="faq-list">' . do_shortcode($content ?? '') . '</div>';
});
add_shortcode('faq_item', function(array $atts, ?string $content = null): string {
$atts = shortcode_atts(['q' => ''], $atts, 'faq_item');
$question = esc_html($atts['q']);
$answer = wp_kses_post(do_shortcode($content ?? ''));
return sprintf(
'<div class="accordion-item js-accordion">
<div class="accordion-title">%s</div>
<div class="accordion-content">%s</div>
</div>',
$question,
$answer
);
});
使用例(投稿エディタで):
[faq]
[faq_item q="WordPressのバックアップはどうすれば良いですか?"]
UpdraftPlusプラグインを使って定期的にバックアップすることを推奨します。
[/faq_item]
[faq_item q="プラグインは何個まで使えますか?"]
公式には制限はありませんが、20〜30個を目安に必要なものだけ使うのがベストプラクティスです。
[/faq_item]
[/faq]
ステップ4:schema.org FAQPageのJSON-LDを出力する
// functions.php — FAQページの構造化データ
add_shortcode('faq', function(array $atts, ?string $content = null): string {
// FAQアイテムを収集(実際の実装では別途パース処理が必要)
$html = '<div class="faq-list">' . do_shortcode($content ?? '') . '</div>';
// JSON-LD(静的サンプル)
$schema = json_encode([
'@context' => 'https://schema.org',
'@type' => 'FAQPage',
'mainEntity' => [
['@type' => 'Question', 'name' => 'Q1', 'acceptedAnswer' => ['@type' => 'Answer', 'text' => 'A1']]
]
], JSON_UNESCAPED_UNICODE);
return $html . '<script type="application/ld+json">' . $schema . '</script>';
});
注意事項
details/summaryタグはJavaScript不要で動作しますが、アニメーションの細かい制御が難しいです。アニメーションが必要な場合はJavaScript版を使用してください- JavaScript版でアコーディオンを複数開けないようにするには、クリック時に他のアコーディオンを全て閉じる処理を追加します
- FAQページでは
schema.org/FAQPageの構造化データを実装するとGoogleのリッチリザルトに表示される場合があります
まとめ
最もシンプルな実装は
/
タグのみ(JS不要)です。アニメーションが必要な場合はJavaScriptで scrollHeight を使って動的に高さを変化させます。アクセシビリティのために aria-expanded を true/false で切り替えてください。