WordPress 6.9で追加されたアコーディオン(開閉)ブロック。以下の例のように、表題をクリックすると中身が表示されるようにするブロックです。
これが中身1です。
H3見出し

これが中身2です。

上の例では「ここをクリックすると中身が開閉します」をクリックすると、文字列と画像が表示されますね。
WordPress標準ではないアコーディオンコンテンツを作るためのブロックを持つプラグインでは、上記の動作とは違って以下のようにスムーズに開閉させることができるものが多いと思います。
これが中身1です。

これが中身2です。

どちらかと言えばピンクの例の方が理想ですよね?
そこで本ページでは、WordPress標準のアコーディオンブロックを使いつつ、スムーズに開閉させるために必要なコードを紹介します。
多分参考ページも少ないですし、やってみてもうまくいかないケースも多かったでしょうから一度試してみては?
アコーディオンブロックの基本的な使い方についてはアコーディオンブロックの使い方(WordPress 6.9以降)をご覧ください。
コードを使用する前に、ここをクリックして注意事項をご確認ください
本ページで掲載しているコードは、以下に了承した上で使用ください
- コードは商用・非商用問わず自由に使っていただいて構いませんが、コード追加による不具合やトラブルが発生しても当方では一切責任を負いません
- コードは有効化しているテーマのfunctions.php、style.cssなどへ追加することで機能します。それらのファイルへの変更を行うことに不安のある方は使用しないでください
- コードは本ページの公開日時点で私の環境において動作したものです。WordPressバージョン他環境の違いによって動作しないことがあります
- コードは、セキュリティ、コードの正確さなどにおいて完全なものではありません。中には紹介するコードを簡略化するために省略している部分があるものもありますので、ご自身でコードを十分に検証し、必要な部分の編集を行った上で使用するようにしてください
- 掲載しているのは参考コードです。自身の環境に合わせるための編集はご自身で対応いただく必要があります(コメント欄等から質問いただいても基本回答は致しません)
- 掲載しているコードの転載を禁じます(SNSで紹介いただいたり、本ページへのリンクを張っていただくことは大歓迎です)
標準のアコーディオンブロック内のコンテンツをスムーズに開閉させるためのコード例
以下のスクリプトをテーマのJSファイルへ追加します。
有効化しているテーマにJSの読み込み機能がないときはこちらクリックして環境作りをしてください
テーマディレクトリ内に「smooth-accordion.js」というJS専用のファイルを作り、functions.phpへ以下のコードを追加します。
function pwcn_smooth_accordion_js_init(){
wp_enqueue_script(
'pwcn-smooth-accordion-js',
get_theme_file_uri('/smooth-accordion.js'),
array(''),
null,
array(
'strategy' => 'defer',
'in_footer' => true, // Note: This is the default value.
)
);
}
add_action('wp_enqueue_scripts','pwcn_smooth_accordion_js_init');
document.addEventListener('DOMContentLoaded', () => {
const accordionButtons = document.querySelectorAll('.wp-block-accordion-heading__toggle');
// ここで設定した秒数が反映されます
const openSpeed = 400; // 開くスピード(400ms = 0.4秒)
const closeSpeed = 150; // 閉じるスピード(150ms = 0.15秒)
accordionButtons.forEach(button => {
button.addEventListener('click', (e) => {
// WordPressコアのJSが動くのをブロックする
e.preventDefault();
e.stopImmediatePropagation();
const item = button.closest('.wp-block-accordion-item');
const panel = item ? item.querySelector('.wp-block-accordion-panel') : null;
if (!item || !panel) return;
// 現在開いているかどうかの判定
const isOpen = item.classList.contains('is-open');
// アニメーション中のガタつきを防ぐ基本処理
panel.style.setProperty('display', 'block', 'important');
panel.style.overflow = 'hidden';
const contentHeight = panel.scrollHeight;
if (!isOpen) {
// 【開くアニメーション】
item.classList.add('is-open'); // 親にクラスをつけて外見をオープン状態に
button.setAttribute('aria-expanded', 'true');
panel.removeAttribute('inert');
panel.animate([
{ height: '0px', opacity: 0 },
{ height: contentHeight + 'px', opacity: 1 }
], {
duration: openSpeed,
easing: 'cubic-bezier(0.25, 1, 0.5, 1)',
fill: 'forwards'
});
setTimeout(() => {
panel.style.height = 'auto';
panel.style.opacity = '1';
}, openSpeed);
} else {
// 【閉じるアニメーション】
item.classList.remove('is-open');
button.setAttribute('aria-expanded', 'false');
panel.setAttribute('inert', '');
const currentHeight = panel.offsetHeight;
const closingAnim = panel.animate([
{ height: currentHeight + 'px', opacity: 1 },
{ height: '0px', opacity: 0 }
], {
duration: closeSpeed,
easing: 'ease-in',
fill: 'forwards'
});
closingAnim.onfinish = () => {
panel.style.removeProperty('display');
panel.style.height = '';
panel.style.opacity = '';
panel.getAnimations().forEach(anim => anim.cancel());
};
}
}, { capture: true }); // コアのJSより「先」にクリックに反応させる設定
});
});
以下のスタイルコードをテーマのスタイルシートへ追加します。
/* アコーディオンの中身(パネル)の初期状態 */
.wp-block-accordion-panel {
display: none;
height: 0;
opacity: 0;
overflow: hidden;
}
/* 開いている時のスタイル */
.wp-block-accordion-item.is-open .wp-block-accordion-panel {
display: block;
height: auto;
opacity: 1;
}
/* 画像の余白によるガタつき防止 */
.wp-block-accordion-panel .wp-block-image {
margin-top: 0;
margin-bottom: 0;
padding: 1rem 0;
}
/* アコーディオンが開く時、中の画像も「箱の広がり」と同じ速度でふわっと同期させる */
.wp-block-accordion-item .wp-block-accordion-panel .wp-block-image img {
transition: opacity 0.3s ease-out;
opacity: 0;
}
.wp-block-accordion-item.is-open .wp-block-accordion-panel .wp-block-image img {
opacity: 1;
}
追加したら既存の投稿の編集画面から、もしくは新規投稿を作成してアコーディオンブロックを挿入して、適当にコンテンツを作って確認してください。
JSコード中の以下の部分を変更することで、開閉速度を調整できますので好みに応じて調整してください。
// ここで設定した秒数が反映されます
const openSpeed = 400; // 開くスピード(400ms = 0.4秒)
const closeSpeed = 150; // 閉じるスピード(150ms = 0.15秒)
スムーズに開閉しないときは以下を確認ください。
- ブラウザキャッシュが残っていて反映されていない→「Ctrl」+「F5」でキャッシュをクリアする
- JSが正常に読み込まれていない→デベロッパーツールにエラーが出ていないか、「pwcn-smooth-accordion-js」というファイルが読み込まれているかを確認する
以上、標準のアコーディオンブロックをスムーズに開閉させる方法でした。
本ページではサイトにあるアコーディオンブロックすべてにスムーズな開閉を適用する方法として紹介しましたが、コードを工夫すれば特定のページにあるアコーディオンブロックのみにしたり、以下のようにアコーディオン内のアコーディオンコンテンツの一部だけをスムーズ開閉にするなどといったこともできますので、上記コードを基礎としてカスタマイズしてみてくださいね。
これが中身です。

これが中身2です。

アコーディオンの見出しをH3以外にしたいときは
標準のアコーディオンブロックの見出しはh3タグで固定して出力され、別のタグへの変更はできなくなっています。
アコーディオンコンテンツを挿入する場所がh2タグのすぐ下にある場合には問題ないのですが、そうでない場合はHTMLの階層構造から逸脱することになってしまい、SEOにマイナスとなる可能性があります。
これを単純にpタグへ変換するコードを以下で紹介しておきますので、よかったら使ってください。
function pwcn_all_accordion_filter_html( $block_content, $block ) {
// アコーディオンアイテムブロックの時だけ処理
if ( 'core/accordion-item' === $block['blockName'] ) {
// 1. 開始タグの置換
// 「wp-block-accordion-heading」というクラス名が含まれる H2〜H6 タグだけをマッチングさせ、<p> に変換
$block_content = preg_replace(
'/<h([2-6])\b([^>]*class="[^"]*wp-block-accordion-heading[^"]*"[^>]*)>/i',
'<p$2>',
$block_content
);
// クラス名の属性順序(classが先か後か)に依存しないよう、もう一つのパターンもカバーしておく
$block_content = preg_replace(
'/<h([2-6])\b([^>]*class=\'[^\']*wp-block-accordion-heading[^\']*\'[^>]*)>/i',
'<p$2>',
$block_content
);
// 2. 終了タグの置換
// ただし、これだけだと中身の見出しの終了タグまで </p> になってしまうのを防ぐため、
// 「直前にアコーディオンのボタンの中身(</button>)がある </h... >」を狙い撃ちします。
// WordPressの標準構造: ...</button></h3 > の並びを利用します。
$block_content = preg_replace( '/(<\/button>)\s*<\/h[2-6]>/i', '$1</p>', $block_content );
}
return $block_content;
}
add_filter( 'render_block', 'pwcn_all_accordion_filter_html', 10, 2 );
アコーディオンコンテンツ(アコーディオンの中身)は自由にブロックが配置されるようになっていて、もちろん見出しタグも含めることができるようになっていますので、それらの階層構造も意識しながらアコーディオンを挿入することをおすすめします
あとがき -詳細ブロックを使う手もある-
ここまで標準のアコーディオンブロック内のコンテンツをスムーズに開閉させる方法を紹介してきましたが、それ以前に導入された詳細ブロック(detailsタグを使った開閉コンテンツブロック)をスムーズに開閉させる方法も以下で紹介しています(例として、コード紹介部分の「有効化しているテーマにJSの読み込み機能がないときはこちらクリックして環境作りをしてください」のところで詳細ブロックのスムース開閉をさせています)。
興味のある方はどうぞ。









コメントを残す