2026年5月20日

2026年5月20日

WordPressでパララックス(視差スクロール)を付ける方法|カバーブロックとCSS・JS

パララックス(視差スクロール)は、スクロールしたときに背景と手前の要素が違う速さで動いて見える表現です。WordPress では、次の3通りで付けられます。

方法 手間 向いている場面
カバーブロックの「固定背景」 コード不要 ブロックエディターで作るページの見出し部分
CSS の background-attachment: fixed CSS を数行 テーマのテンプレートやクラシックエディターのページ
JavaScript で transform を動かす JS とその読み込み 背景以外の要素も動かしたい、速さを細かく決めたい

この記事のブロックの名前とコアの CSS は、2026年10月時点の WordPress(Gutenberg)のソースコードで確認しています。

方法1: カバーブロックの「固定背景」を使う

コードを書かずに付けるなら、カバーブロックの設定を使います。

  1. 投稿や固定ページの編集画面で、カバーブロックを追加し、背景画像を選びます。
  2. カバーブロックを選んだ状態で、右側のブロックの設定サイドバーを開きます。
  3. 「固定背景」をオンにします。

オンにすると、カバーブロックに has-parallax クラスが付き、背景画像に background-attachment: fixed が使われます。スクロールしても背景が画面に固定され、手前の文字や次のブロックだけが動くので、視差があるように見えます。

コアの CSS は、次の2つの場合に固定をやめ、通常のスクロールに戻します。

  • -webkit-touch-callout に対応するブラウザー(iPhone・iPad の Safari など): ソースのコメントでは、モバイルの Safari が背景の固定に正しく対応していないためとされています。
  • OS の設定で「視差効果を減らす」「アニメーションを減らす」などを選んでいる場合(prefers-reduced-motion: reduce)。

そのため、iPhone で見ると背景が普通にスクロールします。これは不具合ではなく、意図された動作です。

方法2: CSSのbackground-attachment: fixedを使う

テーマのテンプレートで見出し部分を作っている場合は、CSS だけで同じ表現ができます。HTML 側に parallax-section クラスを付けた要素を用意し、子テーマの style.css か「外観」→「カスタマイズ」→「追加 CSS」(ブロックテーマではサイトエディターの「スタイル」の「追加 CSS」)に次を書きます。

.parallax-section {
	background-image: url("/wp-content/uploads/2026/10/hero.jpg");
	background-attachment: fixed;
	background-size: cover;
	background-position: center;
	min-height: 60vh;
}

/* iPhone・iPad の Safari では固定をやめる(コアのカバーブロックと同じ判定) */
@supports (-webkit-touch-callout: inherit) {
	.parallax-section {
		background-attachment: scroll;
	}
}

/* 動きを減らす設定の人には固定しない */
@media (prefers-reduced-motion: reduce) {
	.parallax-section {
		background-attachment: scroll;
	}
}
  • 画像の URL は、メディアライブラリで画像を開いたときに表示される「ファイルの URL」に置き換えてください。
  • background-attachment: fixed では、背景画像は要素ではなく画面全体を基準に配置されます。background-size: cover も画面の大きさに合わせて拡大されるため、縦長の画面では画像の左右が大きく切れます。

方法3: JavaScriptで要素を動かす

背景画像だけでなく、画像や見出しなどの要素を、スクロールより遅く動かしたい場合は JavaScript を使います。要素の位置を transform: translateY() で動かすと、top や margin を変える方法と違ってページのレイアウトを計算し直さずに済むため、スクロールが重くなりにくくなります。

HTML

動かしたい要素を外枠(parallax-frame)で囲み、data-parallax 属性で動く量を指定します。0 で動かず、0.15 なら外枠が画面の下端から上端へ通り過ぎる間に、外枠の高さの15%ぶん上下に動き、ページより遅く流れて見えます。ブロックエディターでは「カスタム HTML」ブロックに書くか、テーマのテンプレートに書きます。

<div class="parallax-frame">
	<img src="/wp-content/uploads/2026/10/hero.jpg" alt="" data-parallax="0.15">
</div>
/* 動かす要素がはみ出して見えないように、外枠で切り取る */
.parallax-frame {
	position: relative;
	overflow: hidden;
	height: 60vh;
}

.parallax-frame [data-parallax] {
	position: absolute;
	top: -20%;    /* 上下に動かす分だけはみ出させておく */
	left: 0;
	width: 100%;
	height: 140%;
	object-fit: cover;
	will-change: transform;
}

JavaScript

子テーマに js/parallax.js を作り、次を保存します。

( function () {
	// 動きを減らす設定の人には何もしない
	if ( window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches ) {
		return;
	}

	const items = Array.from( document.querySelectorAll( '[data-parallax]' ) );
	if ( ! items.length ) {
		return;
	}

	// 画面に入っている要素だけを動かす(外枠を監視し、中の要素を記録する)
	const visible = new Set();
	const observer = new IntersectionObserver( function ( entries ) {
		entries.forEach( function ( entry ) {
			const item = entry.target.parallaxItem;
			if ( entry.isIntersecting ) {
				visible.add( item );
			} else {
				visible.delete( item );
			}
		} );
		requestUpdate();
	} );

	function update() {
		const viewportCenter = window.innerHeight / 2;

		visible.forEach( function ( el ) {
			const speed = parseFloat( el.dataset.parallax ) || 0;
			// 動かす要素自身ではなく、外枠の位置を測る(transform の影響を受けないように)
			const frame = el.parentElement.getBoundingClientRect();
			const range = viewportCenter + frame.height / 2;
			// 外枠が画面の下端にあるとき 1、中央で 0、上端で -1
			const progress = Math.max( -1, Math.min( 1, ( frame.top + frame.height / 2 - viewportCenter ) / range ) );

			el.style.transform = 'translateY(' + ( -progress * speed * frame.height ).toFixed( 1 ) + 'px)';
		} );
	}

	// スクロールのたびではなく、画面の描き替え1回につき1回だけ計算する
	let ticking = false;
	function requestUpdate() {
		if ( ticking ) {
			return;
		}
		ticking = true;
		window.requestAnimationFrame( function () {
			update();
			ticking = false;
		} );
	}

	items.forEach( function ( el ) {
		el.parentElement.parallaxItem = el;
		observer.observe( el.parentElement );
	} );

	window.addEventListener( 'scroll', requestUpdate, { passive: true } );
	window.addEventListener( 'resize', requestUpdate );
} )();
  • 外枠(parallax-frame)が画面に入ったときだけ計算するので、ページに要素が多くてもスクロールが重くなりにくくなります。
  • data-parallax は 0.2 以下にします。CSS で上下に20%ずつはみ出させているため、それより大きくすると外枠の中に画像の端が見えます。大きくしたい場合は、CSS の top と height も合わせて広げてください(例: 0.3 なら top: -30% と height: 160%)。

スクリプトを読み込む

子テーマの functions.php に追加します。子テーマのファイルを指すため、get_stylesheet_directory_uri() を使います。

<?php
add_action( 'wp_enqueue_scripts', function (): void {
	$path = get_stylesheet_directory() . '/js/parallax.js';
	if ( ! file_exists( $path ) ) {
		return;
	}

	wp_enqueue_script(
		'wpdr-parallax',
		get_stylesheet_directory_uri() . '/js/parallax.js',
		array(),
		(string) filemtime( $path ),
		array( 'in_footer' => true )
	);
} );
  • 5番目の引数を配列にして in_footer を指定する書き方は、WordPress 6.3 で加わりました。</body> の直前で読み込むため、スクリプトの実行時には HTML の要素がそろっています。
  • バージョンにファイルの更新時刻(filemtime())を使うと、ファイルを書き換えたときにブラウザーのキャッシュが使われ続けるのを防げます。

使うときの注意

  • 動きの大きい表現は、乗り物酔いのような症状を起こす人がいます。どの方法でも、prefers-reduced-motion: reduce のときは動かさないようにしてください。
  • 大きな背景画像はページの表示を遅くします。画面の幅に合った大きさに縮め、WebP などの軽い形式も検討してください。
  • 文字を背景画像の上に重ねる場合は、どの位置にスクロールしても文字が読める濃さのオーバーレイ(カバーブロックでは「オーバーレイ」の色と不透明度)を付けます。

まとめ

  • コードなしで付けるなら、カバーブロックの「固定背景」をオンにする。iPhone の Safari と、動きを減らす設定の環境では、コアの CSS が固定をやめる。
  • CSS で付けるなら background-attachment: fixed。同じく @supports (-webkit-touch-callout: inherit) と prefers-reduced-motion で通常のスクロールに戻す。
  • 要素ごとに速さを変えるなら、JavaScript で transform: translateY() を動かし、requestAnimationFrame で計算の回数を抑え、外枠の位置を測る。

お気軽にご相談ください

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