ページ表示後にスクロールするとスーっと現れるヘッダー。サイトタイトルなどが常時表示されてて格好いいですよね?

まあ格好は置いといて..、クリックするとトップページへ遷移したり、特定ページへのリンクを表示させてそこへジャンプしたり、SNSのシェアボタンなどを表示させるなど、訪問した方が使いやすくなったり、何かをしてもらうきっかけになり、個人的には有用な機能だと思います。

そこで今回は、このページでも上部に表示されるようにしている固定式ヘッダーをプラグインなしでTwenty Twenty-Twoやその他のテーマで実装する方法を紹介します。

スクロールすると表示されるコンテンツ作りの基礎

まずは、ご自身で後にカスタマイズする際に戸惑うことが少なくなると思いますので、本ページで実装したものが実際どのように動作するのかというのを紹介しておきます。

スクロールするとスーっと表示されるコンテンツは以下の機構を設けることで動作します。

  1. スクロール量に応じて表示・非表示を切り替えるスクリプトを作る
  2. 表示させるコンテンツを作る
  3. 表示させるコンテンツのデザインを書く

この流れを今回実装する固定式ヘッダーに置き換えると以下のことをする機能をサイトへ追加していきます。

  1. テーマのテンプレートパーツに全体を「ha-sticky-header」というCSSクラスで囲んだ固定式ヘッダー用のテンプレートを作る
  2. jQueryである程度ページスクロールしたら「is_fix」というCSSクラスを付与するようにするプログラムを追加
  3. CSSで、「is_fix」が追加されたら固定ヘッダーをページ上部へ表示するようにする

要は、最初CSSで非表示にしていたコンテンツをページスクロールに応じてCSSで表示させる、スクロール量はjQueryで計算するというものです。

固定式ヘッダーを作る手順

こちらで配布しているTT2用子テーマを使用していることが前提となっています。独自の子テーマを使用されている場合や別のテーマを使用されている場合は環境に合わせて読み替えてください

1.必要なファイルを準備して子テーマへ転送する

今回の機能追加では、それほど長いコードはありませんので、別ファイル化する必要もないかもとも思いましたが、機能としてまとめておいた方が後々管理しやすいので、以下のようなファイル・フォルダをパソコン上で作成します。

まずは、「sticky-header」というフォルダを作成してください。

その中へ以下のファイル名・拡張子を持つファイルを作成します。

  • sticky-header.js
  • sticky-header-style.css
  • sticky-header.php
  • sticky-header-functions.php

出来上がったら、FTPクライアントツールなどを使って「sticky-header」フォルダごと子テーマへアップロードします。

2.各ファイルのプログラムを作成する

すべてのファイルの操作は、Twenty Twenty-Twoの子テーマの場合は「ツール」→「テーマファイルエディター」で、他のテーマの子テーマの場合は「外観」→「テーマファイルエディター」から行います。

カスタムスクリプト(sticky-header.js)

スクロール量によって表示・非表示させる機能を、jQueryを使って記述します。

テーマファイルエディターを開いたら、右の一覧から「sticky-header」→「sticky-header.js」を開きます。

以下のコードをコピーして貼り付け、保存します。

(function(jQuery) {
 
jQuery(function () {
	var display = function () {
//↓スクロール量によって表示/非表示

//スクロール量の変数を指定
	var fixContact = jQuery('.is_fix');
		scrollPositionTop = jQuery(window).scrollTop();

//画面上から200ピクセルを超えるときだけ表示させる
if((scrollPositionTop > 200)){
             fixContact.fadeIn(400);
    } else {
            fixContact.fadeOut(400);
    }
    };

  jQuery(window).on("scroll", display);

});
})(jQuery);

コード中に注釈を入れていますが、このコードによって、画面上部から200pxを超える場所までスクロールしたら「is_fix」というCSSクラスの付いたコンテンツを表示させる(逆に200px以下では非表示にする)ということをしています。

カスタムCSS(sticky-header-style.css)

表示させる固定コンテンツの位置などを指定するスタイルコードです。

「sticky-header」→「sticky-header-style.css」を開きます。

以下のコードをコピーして貼り付け、保存します。

/** ページ表示時に一旦隠す */
.sample-sticky-header {
	display:none;
}

/** 外枠 **/
.is_fix {
	position:fixed;
	top: 0;
	margin: 0 calc(50% - 50vw);
	padding: 0;
	width:100vw;
	z-index:9999;
	background:#00000090;
}

/** 中のコンテンツ **/
/* 子要素を横並びにする */
.parent{
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	padding: 4px 40px;
	}

/* カスタムロゴを表示 */
.sample-sticky-header img.custom-logo {
	width: 0.8em;
	height: 0.8em;
}

/* 左側の要素(サイトタイトル) */
.inner-left a{
	color:#fff;
	font-size:1.2em;
	text-decoration:none;
}

/* 右側の要素(サイトの説明) */
.inner-right a{
	color:#fff;
	font-size:0.9em;
	text-decoration:none;
}

固定ヘッダーコンテンツ(sticky-header.php)

「sticky-header.js」の動作によって、表示させなさい!となった時に、このファイルに書いた内容が表示されます。

「sticky-header」→「sticky-header.php」を開きます。

以下のコードをコピーして貼り付け、保存します。

<?php if ( !defined( 'ABSPATH' ) ) exit;//このファイルへの直接アクセスを禁止 ?>
<div class="sample-sticky-header is_fix">
	<div class="parent">
		<div class="inner-left">
			<?php the_custom_logo(); ?>
			<a href="<?php echo esc_url(home_url( '/' )); ?>"><?php bloginfo( 'name' ); ?></a></div>
		<div class="inner-right">
			<a href="<?php echo esc_url(home_url( '/' )); ?>"><?php bloginfo( 'description' ); ?></a>
		</div>
	</div>
</div>

表示させる内容はいろいろ工夫できますが、まずは本ページと同じように「サイトのロゴ」「サイトタイトル」と「サイトのキャッチフレーズ」を表示させて動作確認した後、カスタマイズしましょう。

【補足説明】

このコード中の以下の部分に書かれている「is_fix」というCSSクラスをjsとcssで表示・非表示させています。

<div class="sample-sticky-header is_fix">

つまり...

  1. まずは「sample-sticky-header」をCSSで一旦非表示にする
  2. スクロール量が200pxを超えたら「is_fix」を表示させる指示をjsで与える
  3. CSSで「sample-sticky-header」と「is_fix」の両方を持つ場合の表示方法を指示して表示させる

という風にして、表示・非表示させているのです。

各ファイルを機能させるためのPHPプログラム(sticky-header-functions.php)

これまで作ったCSS、jQuery、コンテンツをサイトに組み込むためのプログラムを作成します。

「sticky-header」→「sticky-header-functions.php」を開きます。

以下のコードをコピーして貼り付け、保存します。

<?php
/* このファイルへの直接アクセスを禁止 */
if ( !defined( 'ABSPATH' ) ) exit; 

/* スクリプトの読み込み */
if ( !function_exists( 'sample_sticky_header_script_include' ) ){
function sample_sticky_header_script_include() {
	if(!wp_is_mobile()){
	wp_enqueue_script( 'sticky-header-script', get_stylesheet_directory_uri() .'/sticky-header/sticky-header.js', array('jquery'), '1.0.0' );
}
}
}
add_action( 'wp_enqueue_scripts', 'sample_sticky_header_script_include' );

/* スタイルの登録と読み込み */
if ( !function_exists( 'sample_sticky_header_styles_enqueue' ) ){
function sample_sticky_header_styles_enqueue() {
//スタイルシートの登録
wp_register_style( 'sticky-header-style', get_stylesheet_directory_uri() .'/sticky-header/sticky-header-style.css', array(), filemtime(get_stylesheet_directory() .'/style.css'), 'all' );

//スタイルシートの読み込み
	if(!wp_is_mobile()){
		wp_enqueue_style('sticky-header-style', '', array(), '1.0', false);
	}
}
}
add_action( 'wp_footer', 'sample_sticky_header_styles_enqueue');

/* コンテンツをフッターへ出力 */
if ( !function_exists( 'sample_header_content_init' ) ){
function sample_header_content_init(){
	get_template_part('/sticky-header/sticky-header');
}
}
if(!wp_is_mobile()){
add_action('wp_footer','sample_header_content_init');
}

/* 管理バーがある場合に表示をずらす */
if ( !function_exists( 'sample_sticky_header_admin_bar' ) ){
function sample_sticky_header_admin_bar(){
	if ( is_admin_bar_showing() && !wp_is_mobile()) {
		echo '<style>.sample-sticky-header {margin-top:32px!important;}</style>';
}
}
}

add_action('wp_footer','sample_sticky_header_admin_bar');

3.動作させてみる

ここまでやってもまだ固定式ヘッダーは表示されません。なぜって?

それは、いろいろなファイルを作って、それを読み込むためのプログラムを組んでも、まだサイトには読み込まれていないからです。

最後に以下のコードを子テーマのfunctions.phpへ追加して完成です。

/* 固定式ヘッダー */
include (get_stylesheet_directory() .'/sticky-header/sticky-header-functions.php');

上記コードを貼り付けて保存したらエラーとなった場合には、これまで作成やコピーしたコードのどこかに間違いがありますので、よく確認してください


ここまでで問題なく設置できれば、スクロールした時ページ上部に本ページと同じような固定ヘッダーが表示されるはずです。

表示されない場合には以下をご確認ください。

  • ファイル名・拡張子・コードは合っているか?
  • ページ表示した状態でキャッシュのクリア「Ctrl」+「F5」して正常に動作するか?
  • デベロッパーツールで確認してjQueryのエラーが出ていないか?

固定ヘッダーに自動でメニューを表示させたいときは

ここからはおまけ情報として、今回作った固定ヘッダーに、任意のメニューを表示できないか?というのをいろいろと試行錯誤したことを紹介しておきます。

ブロックテーマ

Twenty Twenty-Twoのようなブロックテーマの場合、グローバルメニュー(メニュー)はテーマエディターから「テーマ」カテゴリーの「ナビゲーション」ブロックを使って作成します。

この「ナビゲーション」ブロックで作成したメニューは、テーマテンプレートやテンプレートパーツと同様に、投稿と同じデータとしてデータベース上に保存されるため、容易にいい形で呼び出すことができません。

また、「テーマ」関連のブロックは他のブロックのようにHTMLとして吐き出すこともできませんので、本ページで作成した固定ヘッダー用のテンプレート内に配置することもできません。

したがって、以下の方法のいずれかで実装するしかないというのが結論でした。

個人的には、必要なページへのリンクをHTMLで作れば、何も自動でメニューを表示させる必要もないので、苦労する必要はないのではないかと思います。

テンプレートパーツとして作って適用させる

この方法では以下の調整を行う必要があります

  • テンプレートレイアウトの状態によっては全幅表示の調整に苦労する
  • カバーブロックで全幅表示させると、半透明の指定調整が必要、また、内包するコンテンツがクリッカブルにならないので工夫が必要

いろいろ試行錯誤しましたが、上記2点がきれいに調整できなかったので、個人的にはあまりおすすめしません。

以下の手順で実装自体は可能です。

  1. これまでの作成手順の中の、各ファイルを機能させるためのPHPプログラムのコード中にある、テンプレートをフッターで読み込む部分を削除
  2. テンプレートパーツを新規作成し、カバーブロックを入れ、その中にメニュー他コンテンツを挿入
  3. カバーブロックの追加CSSクラスに「sample-sticky-header is_fix」を指定
  4. ブロックテーマの各テンプレートにテンプレートパーツを追加
  5. 表示された固定ヘッダーに対してCSSの調整

再利用ブロックで作成して適用させる

前項のテンプレートパーツよりは調整しやすい感がありますが、こちらも結局きれいに実装はできませんでした。

以下の手順で実装は可能です。

  1. こちらを参考に、PHPプログラム上で再利用ブロックを呼び出せるようにする
  2. 再利用ブロックで、固定ヘッダーコンテンツを作成する
  3. 固定ヘッダーコンテンツ(sticky-header.php)を以下(リストの下)のコードに差し替え
  4. 表示されたコンテンツをCSSで調整
<?php if ( !defined( 'ABSPATH' ) ) exit;//このファイルへの直接アクセスを禁止 ?>
<div class="sample-sticky-header is_fix">
<?php sample_get_block(再利用ブロックのID); ?>
</div>

クラシックテーマと同じ処理をさせるようにする

これが一番現実的かも知れません。

以下のようにしてクラシックテーマと同じようにメニューを作れるようにします。

  1. テーマカスタマイザーを復活させる
  2. テーマカスタマイザー上に「メニュー」の項目を復元する
  3. メニューを作る
  4. クラシックテーマの場合と同じようにしてテンプレート内にメニューを表示させる
  5. 見た目をCSSで調整する

本ページと直接関係ない内容なので、1および2の方法については割愛しますから、ご自身でお調べになってください(こちらのページでカスタマイザー関連のことに触れていますので参考にご覧ください)

クラシックテーマの場合

クラシックテーマの場合は、ブロックテーマと違ってナビメニューが独立しているので、比較的簡単です。

以下の手順で実装できます。

  1. テーマカスタマイザーで固定ヘッダー用のメニューを作る
  2. 固定ヘッダーコンテンツ(sticky-header.php)を以下(リストの下)のコードに差し替え
  3. 表示内容をCSSで調整
<?php if ( !defined( 'ABSPATH' ) ) exit;//このファイルへの直接アクセスを禁止 ?>
<div class="sample-sticky-header is_fix">
	<?php wp_nav_menu( array(
		'theme_location' => '〇〇',
		'container' => '〇〇',
		'container_class' => '〇〇',
		'container_id' => '〇〇',
		'fallback_cb' => ''
		) ); ?>
</div>

〇〇の部分はテーマによって異なりますのでお調べください