2026年5月20日

2026年5月20日

WordPressでパララックス効果を実装する方法

はじめに

パララックス効果は、スクロールに合わせて背景と前景の要素が異なる速度で動く視差効果です。ページに奥行き感と動的な印象を与えます。CSSの background-attachment: fixed か、JavaScriptの transform で実装できます。

症状・原因

  • ヒーローセクションの背景に視差効果を付けたい
  • スクロールで要素がゆっくり動くエフェクトを実装したい
  • パララックスのパフォーマンスを最適化したい
  • モバイルでもパララックスを適切に制御したい

解決手順

ステップ1:CSSのみでシンプルなパララックス

/* style.css — background-attachment: fixed */
.parallax-section {
    background-image: url('/wp-content/themes/my-theme/images/hero-bg.jpg');
    background-attachment: fixed;
    background-size: cover;
    background-position: center;
    min-height: 500px;
}

/* モバイルでは無効化(パフォーマンス・見た目の問題) */
@media (max-width: 768px) {
    .parallax-section {
        background-attachment: scroll;
    }
}

ステップ2:JavaScriptで滑らかなパララックス

// js/parallax.js
document.addEventListener('DOMContentLoaded', function() {
    const elements = document.querySelectorAll('[data-parallax]');
    if (!elements.length) return;

    function updateParallax() {
        const scrollY = window.scrollY;

        elements.forEach(function(el) {
            const speed  = parseFloat(el.dataset.parallax) || 0.5;
            const rect   = el.getBoundingClientRect();
            const center = rect.top + rect.height / 2 - window.innerHeight / 2;

            // transform: translateY でGPUを使う(repaintなし)
            el.style.transform = `translateY(${center * speed}px)`;
        });
    }

    // requestAnimationFrame でパフォーマンス最適化
    let ticking = false;
    window.addEventListener('scroll', function() {
        if (!ticking) {
            requestAnimationFrame(function() {
                updateParallax();
                ticking = false;
            });
            ticking = true;
        }
    }, { passive: true });

    updateParallax();
});

HTMLでの使い方:

<!-- data-parallax 属性でスピードを指定(0.1〜0.9) -->
<div class="hero-section">
    <img src="hero-bg.jpg" data-parallax="0.4" alt="">
    <h1 data-parallax="0.1">見出し(ゆっくり動く)</h1>
</div>

ステップ3:Gutenbergカバーブロックにパララックスを適用

// functions.php — カバーブロックのHTMLを加工
add_filter('render_block', function(string $html, array $block): string {
    if ($block['blockName'] !== 'core/cover') return $html;
    if (empty($block['attrs']['useFeaturedImage'])) return $html;

    // パララックス用クラスを追加
    return str_replace('wp-block-cover', 'wp-block-cover parallax-section', $html);
}, 10, 2);
/* style.css — Gutenbergカバーブロックのパララックス */
.wp-block-cover.parallax-section .wp-block-cover__image-background {
    transform: translateY(0);
    transition: none;
    will-change: transform;
}

ステップ4:Intersection Observer でビューポート外は停止

// js/parallax.js — ビューポート外の要素はスキップ
const observer = new IntersectionObserver(function(entries) {
    entries.forEach(function(entry) {
        entry.target.dataset.visible = entry.isIntersecting ? '1' : '0';
    });
});

elements.forEach(function(el) {
    observer.observe(el);
    el.dataset.visible = '0';
});

function updateParallax() {
    elements.forEach(function(el) {
        if (el.dataset.visible !== '1') return; // 非表示はスキップ
        // ...translate処理
    });
}

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

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

注意事項

  • background-attachment: fixed はiOSのSafariで正常に動作しません。モバイルでは background-attachment: scroll に切り替えてください
  • パララックスはパフォーマンスに影響するため、transform: translateY() + will-change: transform を使いGPU合成レイヤーに昇格させてください。topmargin を直接変更すると再レイアウトが発生しパフォーマンスが悪化します
  • requestAnimationFrame + ticking フラグでスクロールイベントの処理頻度を制限してください

まとめ

最もシンプルな実装は background-attachment: fixed(CSS1行)です。カスタムJavaScript版は transform: translateY() + requestAnimationFrame で実装し、data-parallax="0.4" で速度を指定します。モバイルでは @media (max-width: 768px) で無効化するのを忘れずに。

お気軽にご相談ください

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