Personal WP Customization Notes (PWCN)

WordPressで実際に行ったカスタマイズの記録、発生した問題への対処時のメモ、ブロックテーマのカスタマイズなど

モバイルアクセス時に画面下へメニューボタンコンテンツを固定表示させるコード例

パソコン表示時に画面隅に表示させることの多い「ホームへ戻る」「ページ上部へ戻る」と、ヘッダーに表示させることの多いナビゲーションメニューですが、モバイルでは画面サイズが小さいので非表示にしているサイトが多いと思います。

そこで回遊性を上げるため、Fixed Bottom Menuというプラグインなどを使ったり、機能が実装されたテーマを使ったりして、スマホ画面の下部にこれらをまとめて常時させるというサイトもたくさんありますね。

もちろんプラグインや機能を持つテーマを利用することも手かとは思いますが、汎用に利用できるようにするために細かく設定ができるようになっていて余分なコードが吐き出されて多少なりともパフォーマンスに影響が出ることもあります。

そこで今回は、プラグインや機能を持つテーマを使わずに、モバイルアクセス時に「ホームへ戻る」「任意のメニューをポップアップ表示させる」「画面上部へ戻る」ボタンを画面下部に固定表示させるコード例を紹介しようと思います。

お使いのテーマによってスタイルの調整が必要な場合があると思いますが、仕様が決まっていて軽量に動かしたい方にはおすすめの方法かと思います。

この機構は現在本サイトでも採用しています。どんな表示ができるのかはスマホからアクセスして確認してみてくださいね。

モバイル下部固定メニューを実装する手順

まずはベタ書きして動作確認

以下が、有効化しているテーマのfunctions.phpだけにコードを追加して実装するためのコード例です。

この方法は、ひとまず動作するかを確認するために紹介するもので、HTMLソースに、タグもスタイルコードもJSもすべて出力されてしまって動作はするけどソース上美しくないので、次項で整理してすっきり出力させるようにすることをおすすめします

/***** モバイルフッター固定メニュー *****/
/*** モバイル用カスタムメニューの位置を登録 ***/
function pwcn_register_mobile_footer_menu() {
	register_nav_menus(
		array(
			'pwcn_mobile_footer_menu' => 'モバイル固定フッターに表示させるメニューとして使用する',
		)
	);
}
add_action( 'init', 'pwcn_register_mobile_footer_menu' );

/*** モバイル判定(wp_is_mobile)を使ってフッターを出力 ***/
function pwcn_render_mobile_fixed_footer() {
?>
<div id="pwcn-mobile-fixed-footer" class="pwcn-mobile-fixed-footer">
	<!-- ① Homeへ戻る -->
		<a href="<?php echo esc_url( home_url('/') ); ?>" class="pwcn-footer-item">
			<span class="icon">🏠</span>
			<span class="label">ホーム</span>
	</a>

	<!-- ② メニューボタン & ポップアップメニュー -->
	<div class="pwcn-footer-menu-wrapper">
		<button type="button" id="pwcn-menu-toggle-btn" class="pwcn-footer-item menu-btn">
			<span class="icon">☰</span>
			<span class="label">メニュー</span>
		</button>
            
		<!-- タップ時にフッターの上に展開するポップアップ -->
		<div id="pwcn-footer-popup-menu" class="pwcn-footer-popup-menu">
			<?php
				wp_nav_menu( array(
					'theme_location' => 'pwcn_mobile_footer_menu',
					'container'      => false,
					'fallback_cb'    => false, // メニュー未設定時は非表示
				) );
			?>
		</div>
	</div>

	<!-- ③ ページ上部へ戻る -->
	<button type="button" id="pwcn-page-top-btn" class="pwcn-footer-item top-btn">
		<span class="icon">↑</span>
		<span class="label">トップ</span>
	</button>
</div>

<style>
/* 固定フッター全体のスタイル(初期状態は画面下に隠す) */
.pwcn-mobile-fixed-footer {
	position: fixed;
	bottom: 0;
	left: 0;
	width: 100%;
	background-color: #ffffff;
	box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
	display: flex;
	justify-content: space-around;
	align-items: center;
	z-index: 99999;
	padding: 8px 0;
	transform: translateY(100%);
	transition: transform 0.3s ease;
	box-sizing: border-box;
}

/* スクロール後に付与される表示用クラス */
.pwcn-mobile-fixed-footer.is-visible {
	transform: translateY(0);
}

/* 各ボタンの共通スタイル */
.pwcn-mobile-fixed-footer .pwcn-footer-item,
.pwcn-mobile-fixed-footer .pwcn-footer-menu-wrapper button {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-decoration: none;
	color: #333333;
	font-size: 11px;
	background: none;
	border: none;
	padding: 0;
	cursor: pointer;
}

.pwcn-mobile-fixed-footer .icon {
	font-size: 18px;
	margin-bottom: 2px;
	line-height: 1;
	}

/* メニューボタン周辺の親要素 */
.pwcn-footer-menu-wrapper {
	position: relative;
}

/* ポップアップメニュー(初期状態は非表示・フェードアウト) */
.pwcn-footer-popup-menu {
	position: absolute;
	bottom: 130%; /* フッターの少し上に配置 */
	left: 50%;
	transform: translateX(-50%) scale(0.95);
	background-color: #ffffff;
	box-shadow: 0 -4px 15px rgba(0, 0, 0, 0.15);
	border-radius: 8px;
	padding: 12px 16px;
	min-width: 160px;
	opacity: 0;
	visibility: hidden;
	transition: all 0.25s ease;
	box-sizing: border-box;
}

/* メニューが開いた時の状態 */
.pwcn-footer-popup-menu.is-active {
	opacity: 1;
	visibility: visible;
	transform: translateX(-50%) scale(1);
}

/* WordPress標準メニューのリスト(縦並び) */
.pwcn-footer-popup-menu .menu {
	list-style: none;
	margin: 0;
	padding: 0;
}

.pwcn-footer-popup-menu .menu li {
	margin: 0;
	border-bottom: 1px solid #f0f0f0;
}

.pwcn-footer-popup-menu .menu li:last-child {
	border-bottom: none;
}

.pwcn-footer-popup-menu .menu li a {
	display: block;
	padding: 10px 0;
	color: #333333;
	text-decoration: none;
	font-size: 13px;
	text-align: center;
}

.pwcn-footer-popup-menu .menu li a:hover {
	color: #0073aa;
}
</style>

<script>
document.addEventListener('DOMContentLoaded', function() {
	const footer = document.getElementById('pwcn-mobile-fixed-footer');
	const topBtn = document.getElementById('pwcn-page-top-btn');
	const menuBtn = document.getElementById('pwcn-menu-toggle-btn');
	const popupMenu = document.getElementById('pwcn-footer-popup-menu');

	// 一定以上スクロールしたらフッターを表示
	window.addEventListener('scroll', function() {
		if (window.scrollY > 200) {
			footer.classList.add('is-visible');
		} else {
			footer.classList.remove('is-visible');
			popupMenu.classList.remove('is-active'); // フッターが消えたらメニューも閉じる
		}
	});

	// 「メニュー」ボタンタップでポップアップを開閉
	if (menuBtn && popupMenu) {
		menuBtn.addEventListener('click', function(e) {
			e.stopPropagation(); // イベントのバブリングを防止
			popupMenu.classList.toggle('is-active');
		});

		// メニューの「外側」をタップしたら閉じる
		document.addEventListener('click', function(e) {
			if (!popupMenu.contains(e.target) && !menuBtn.contains(e.target)) {
				popupMenu.classList.remove('is-active');
			}
		});
	}

	// ページ上部へスムーズスクロール
	if (topBtn) {
		topBtn.addEventListener('click', function() {
			window.scrollTo({
				top: 0,
				behavior: 'smooth'
			});
		});
	}
});
</script>
<?php
}

/* wp_is_mobileでモバイルの場合のみ出力 */
if ( function_exists('wp_is_mobile') && wp_is_mobile() ) {
	add_action('wp_footer', 'pwcn_render_mobile_fixed_footer');
}

メニューボタンをクリックした時のメニューを作る

本ページで実装するボタンの中に「メニューをポップアップ表示させる」ボタンがあり、前述のコードを入れただけの状態で「メニュー」ボタンをタップしても何も表示されないので、試しに専用のメニューを作ってみましょう。

サイトの管理画面から「外観」→「メニュー」を選択して、メニューの新規作成をします。

「モバイル固定メニュー」などと名付け、ひとまず適当なページを追加して、右側画面の下部にある「モバイル固定フッターに表示させるメニューとして使用する」にチェックを入れて保存します。

保存したらモバイル画面をリロードして、「メニュー」ボタンをタップした時に先ほど追加したメニュー項目がポップアップ表示されれば実装完了です。

先程作成したメニューで、URLに「#」を指定した「カスタムリンク」を追加してその中に子メニューとしてページを入れることで階層メニューとして表示させることもできます

表示をスマートフォンだけに限定したい時は

上記のコードでは、モバイルかどうかの判定に、WordPressの組み込み関数である「wp_is_mobile」を使用していて、この関数はタブレット端末もモバイルとして判定するようになっています。

タブレットは除外してスマートフォンだけに限定したい場合には、以下のページを参考に「is_mobile()」という関数を作り、「wp_is_mobile」の部分(2か所)を「is_mobile()」へ変更しましょう。

WordPressの作法に従ってHTMLをすっきりさせるコード

先ほど紹介したコードでも動作しますし、セキュリティの問題などもありませんが、WordPressらしく?スタイルはスタイルシートで、JavaScriptはjsファイルで処理するようにしておくと、HTMLのソースがすっきりします。

この方法にしたからといって、パフォーマンスに違いが出たり、処理に違いが出ることはありませんが、お使いのテーマにstyle.css(テーマの認識のためだけに設置されている場合があるので読み込みされているかの確認が必要)とcustom.jsなどのスクリプトを読み込ませるためのファイルが存在する場合には、こちらの方法がおすすめです。

また、テーマを変更した場合でも機能を移植しないで済むように、以下を参考に独自のプラグインを作ったり、当サイトで配布しているHima Art My Functionsプラグインを使用することも併せておすすめします。

単純に以下のようにPHPプログラムとスタイルコード、JSをそれぞれ適したファイルへ書くだけです。

PHPには以下のプログラムコードを追加します。

/***** モバイルフッター固定メニュー *****/
/*** モバイル用カスタムメニューの位置を登録 ***/
function pwcn_register_mobile_footer_menu() {
	register_nav_menus(
		array(
			'pwcn_mobile_footer_menu' => 'モバイル固定フッターに表示させるメニューとして使用する',
		)
	);
}
add_action( 'init', 'pwcn_register_mobile_footer_menu' );

/*** モバイル判定(wp_is_mobile)を使ってフッターを出力 ***/
function pwcn_render_mobile_fixed_footer() {
?>
<div id="pwcn-mobile-fixed-footer" class="pwcn-mobile-fixed-footer">
	<!-- ① Homeへ戻る -->
		<a href="<?php echo esc_url( home_url('/') ); ?>" class="pwcn-footer-item">
			<span class="icon">🏠</span>
			<span class="label">ホーム</span>
	</a>

	<!-- ② メニューボタン & ポップアップメニュー -->
	<div class="pwcn-footer-menu-wrapper">
		<button type="button" id="pwcn-menu-toggle-btn" class="pwcn-footer-item menu-btn">
			<span class="icon">☰</span>
			<span class="label">メニュー</span>
		</button>
            
		<!-- タップ時にフッターの上に展開するポップアップ -->
		<div id="pwcn-footer-popup-menu" class="pwcn-footer-popup-menu">
			<?php
				wp_nav_menu( array(
					'theme_location' => 'pwcn_mobile_footer_menu',
					'container'      => false,
					'fallback_cb'    => false, // メニュー未設定時は非表示
				) );
			?>
		</div>
	</div>

	<!-- ③ ページ上部へ戻る -->
	<button type="button" id="pwcn-page-top-btn" class="pwcn-footer-item top-btn">
		<span class="icon">↑</span>
		<span class="label">トップ</span>
	</button>
</div>
<?php
}

/* wp_is_mobileでモバイルの場合のみ出力 */
if ( function_exists('wp_is_mobile') && wp_is_mobile() ) {
	add_action('wp_footer', 'pwcn_render_mobile_fixed_footer');
}

スタイルシートには以下のスタイルコードを追加します。

/* 固定フッター全体のスタイル(初期状態は画面下に隠す) */
.pwcn-mobile-fixed-footer {
	position: fixed;
	bottom: 0;
	left: 0;
	width: 100%;
	background-color: #ffffff;
	box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
	display: flex;
	justify-content: space-around;
	align-items: center;
	z-index: 99999;
	padding: 8px 0;
	transform: translateY(100%);
	transition: transform 0.3s ease;
	box-sizing: border-box;
}

/* スクロール後に付与される表示用クラス */
.pwcn-mobile-fixed-footer.is-visible {
	transform: translateY(0);
}

/* 各ボタンの共通スタイル */
.pwcn-mobile-fixed-footer .pwcn-footer-item,
.pwcn-mobile-fixed-footer .pwcn-footer-menu-wrapper button {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-decoration: none;
	color: #333333;
	font-size: 11px;
	background: none;
	border: none;
	padding: 0;
	cursor: pointer;
}

.pwcn-mobile-fixed-footer .icon {
	font-size: 18px;
	margin-bottom: 2px;
	line-height: 1;
	}

/* メニューボタン周辺の親要素 */
.pwcn-footer-menu-wrapper {
	position: relative;
}

/* ポップアップメニュー(初期状態は非表示・フェードアウト) */
.pwcn-footer-popup-menu {
	position: absolute;
	bottom: 130%; /* フッターの少し上に配置 */
	left: 50%;
	transform: translateX(-50%) scale(0.95);
	background-color: #ffffff;
	box-shadow: 0 -4px 15px rgba(0, 0, 0, 0.15);
	border-radius: 8px;
	padding: 12px 16px;
	min-width: 160px;
	opacity: 0;
	visibility: hidden;
	transition: all 0.25s ease;
	box-sizing: border-box;
}

/* メニューが開いた時の状態 */
.pwcn-footer-popup-menu.is-active {
	opacity: 1;
	visibility: visible;
	transform: translateX(-50%) scale(1);
}

/* WordPress標準メニューのリスト(縦並び) */
.pwcn-footer-popup-menu .menu {
	list-style: none;
	margin: 0;
	padding: 0;
}

.pwcn-footer-popup-menu .menu li {
	margin: 0;
	border-bottom: 1px solid #f0f0f0;
}

.pwcn-footer-popup-menu .menu li:last-child {
	border-bottom: none;
}

.pwcn-footer-popup-menu .menu li a {
	display: block;
	padding: 10px 0;
	color: #333333;
	text-decoration: none;
	font-size: 13px;
	text-align: center;
}

.pwcn-footer-popup-menu .menu li a:hover {
	color: #0073aa;
}

JSファイルには以下のプログラムコードを追加します。

document.addEventListener('DOMContentLoaded', function() {
	const footer = document.getElementById('pwcn-mobile-fixed-footer');
	const topBtn = document.getElementById('pwcn-page-top-btn');
	const menuBtn = document.getElementById('pwcn-menu-toggle-btn');
	const popupMenu = document.getElementById('pwcn-footer-popup-menu');

	// 一定以上スクロールしたらフッターを表示
	window.addEventListener('scroll', function() {
		if (window.scrollY > 200) {
			footer.classList.add('is-visible');
		} else {
			footer.classList.remove('is-visible');
			popupMenu.classList.remove('is-active'); // フッターが消えたらメニューも閉じる
		}
	});

	// 「メニュー」ボタンタップでポップアップを開閉
	if (menuBtn && popupMenu) {
		menuBtn.addEventListener('click', function(e) {
			e.stopPropagation(); // イベントのバブリングを防止
			popupMenu.classList.toggle('is-active');
		});

		// メニューの「外側」をタップしたら閉じる
		document.addEventListener('click', function(e) {
			if (!popupMenu.contains(e.target) && !menuBtn.contains(e.target)) {
				popupMenu.classList.remove('is-active');
			}
		});
	}

	// ページ上部へスムーズスクロール
	if (topBtn) {
		topBtn.addEventListener('click', function() {
			window.scrollTo({
				top: 0,
				behavior: 'smooth'
			});
		});
	}
});

コメントを残す

メールアドレスが公開されることはありません。※ が付いている欄は必須項目です

※リンクやURLの挿入されているコメントは無視します