2026年5月20日

2026年5月20日

WordPressでモーダルダイアログを実装する方法

はじめに

モーダルダイアログは、クリック時にページ上にオーバーレイ表示するUI要素です。お知らせポップアップ・画像拡大・フォーム表示などに使われます。WordPressではショートコードと組み合わせることでページエディタから簡単に呼び出せます。

症状・原因

  • ボタンクリックでポップアップを表示したい
  • モーダル外クリックやESCキーで閉じたい
  • アクセシビリティに配慮したモーダルを実装したい
  • ショートコードでモーダルをページに追加したい

解決手順

ステップ1:モーダルのHTML・CSS構造

/* style.css */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s, visibility 0.25s;
}

.modal-overlay.is-open {
    opacity: 1;
    visibility: visible;
}

.modal-dialog {
    background: #ffffff;
    border-radius: 8px;
    padding: 32px;
    max-width: 560px;
    width: 90%;
    max-height: 80vh;
    overflow-y: auto;
    transform: scale(0.9);
    transition: transform 0.25s;
    position: relative;
}

.modal-overlay.is-open .modal-dialog {
    transform: scale(1);
}

.modal-close {
    position: absolute;
    top: 12px;
    right: 16px;
    background: none;
    border: none;
    font-size: 24px;
    cursor: pointer;
    line-height: 1;
    color: #50575e;
}

ステップ2:JavaScriptでモーダル制御

// js/modal.js
document.addEventListener('DOMContentLoaded', function() {

    // モーダルを開く
    document.querySelectorAll('[data-modal-target]').forEach(function(trigger) {
        trigger.addEventListener('click', function() {
            const id = this.dataset.modalTarget;
            const modal = document.getElementById(id);
            if (!modal) return;

            modal.classList.add('is-open');
            modal.setAttribute('aria-hidden', 'false');
            document.body.style.overflow = 'hidden';

            // フォーカスをモーダル内の最初の要素に移動
            const firstFocusable = modal.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
            if (firstFocusable) firstFocusable.focus();
        });
    });

    // モーダルを閉じる
    function closeModal(modal) {
        modal.classList.remove('is-open');
        modal.setAttribute('aria-hidden', 'true');
        document.body.style.overflow = '';
    }

    // 閉じるボタン
    document.querySelectorAll('.modal-close, [data-modal-close]').forEach(function(btn) {
        btn.addEventListener('click', function() {
            const modal = this.closest('.modal-overlay');
            if (modal) closeModal(modal);
        });
    });

    // オーバーレイクリックで閉じる
    document.querySelectorAll('.modal-overlay').forEach(function(overlay) {
        overlay.addEventListener('click', function(e) {
            if (e.target === this) closeModal(this);
        });
    });

    // ESCキーで閉じる
    document.addEventListener('keydown', function(e) {
        if (e.key === 'Escape') {
            document.querySelectorAll('.modal-overlay.is-open').forEach(closeModal);
        }
    });
});

ステップ3:ショートコードでモーダルを呼び出す

// functions.php — モーダルショートコード
add_shortcode('modal', function(array $atts, ?string $content = null): string {
    $atts = shortcode_atts([
        'id'     => 'modal-' . wp_rand(1000, 9999),
        'button' => 'ポップアップを開く',
        'title'  => '',
    ], $atts, 'modal');

    $id    = esc_attr($atts['id']);
    $label = esc_html($atts['button']);
    $title = esc_html($atts['title']);

    ob_start();
    ?>
    <button data-modal-target="<?= $id ?>" class="wp-element-button">
        <?= $label ?>
    </button>

    <div id="<?= $id ?>" class="modal-overlay" role="dialog" aria-modal="true"
         aria-label="<?= $title ?>" aria-hidden="true">
        <div class="modal-dialog">
            <?php if ($title): ?>
                <h2><?= $title ?></h2>
            <?php endif; ?>
            <button class="modal-close" aria-label="閉じる">✕</button>
            <?= wp_kses_post(do_shortcode($content)) ?>
        </div>
    </div>
    <?php
    return ob_get_clean();
});

使用例(投稿エディタで):

[modal id="info-modal" button="詳細を見る" title="サービス詳細"]
ここにモーダルの内容を記述します。
[/modal]

ステップ4:スクリプトのエンキュー

// functions.php
add_action('wp_enqueue_scripts', function(): void {
    wp_enqueue_script(
        'modal-dialog',
        get_template_directory_uri() . '/js/modal.js',
        [],
        filemtime(get_template_directory() . '/js/modal.js'),
        true
    );
});

注意事項

  • モーダル表示中は document.body.style.overflow = 'hidden' でバックグラウンドのスクロールを止めてください。閉じたら必ず解除します
  • アクセシビリティのために role="dialog"aria-modal="true"aria-hidden を正確に設定してください。スクリーンリーダーはこれらの属性を参照します
  • wp_kses_post() でモーダルコンテンツをサニタイズしてXSS攻撃を防いでください

まとめ

モーダルは position: fixed; inset: 0 のオーバーレイ + .is-open クラスで表示制御します。ESCキー・オーバーレイクリック・閉じるボタンの3つの閉じ方を実装し、role="dialog" + aria-modal="true" でアクセシビリティに対応します。ショートコードにすることでエディタから簡単に呼び出せます。

お気軽にご相談ください

お見積りへ お問い合わせへ