カテゴリー
CSS jQuery PHP Twenty Twenty Webサイト作成 WordPress

スクロール時にヘッダーを固定する

「スクロール時にナビゲーションメニューを固定する」は私が管理している別サイトのお話だったので、直接ナビゲーションメニューが固定される様子をお見せすることができませんでした。

そこで今回は本サイトで同じような修正を行ってみます。

ただ、Twenty Twenty(本サイトが使用しているテーマ)では、ナビゲーションメニューを含むヘッダーがもともと最上部に表示されており、スクロール量に関係なくただ固定するだけになって面白くないので下記のように趣向を変えてみました。

要求仕様
  1. ヘッダーは上スクロール時のみ固定し、下スクロール時は固定しない。
  2. ただし、下スクロール後ヘッダーの一部が表示されている状態から上スクロールする場合はヘッダーを固定しない。
  3. ヘッダー固定状態から上スクロールする場合、スクロール量が0になったらヘッダー固定を解除する。
  4. ヘッダー固定時はヘッダーの背景を透明にする。

では、「スクロール時にナビゲーションメニューを固定する」と同じ順番で説明していきます。

目次 [閉じる]
  1. jQueryコードの作成
  2. jQueryファイルの読み込み
  3. CSSの設定

1. jQueryコードの作成

今回作成したjQueryコードは下記のようになります。

//
// 上スクロール時ヘッダーを固定する
//
jQuery(function() {
    var _window = jQuery(window),
        _head = jQuery('#site-header'),
        _bread = jQuery('#breadcrumb'),
	headHeight = _head.outerHeight(),
	startPos = 0;

    _window.on('load scroll', function() {
	var scroll = jQuery(this).scrollTop();
        if((scroll < startPos) && (scroll > headHeight)) {
    	    if (_head.hasClass('fixed') == false) {
   	        _head.addClass('fixed');
	        _bread.css('padding-top', headHeight + 'px');
	    }
        } else if ((scroll >= startPos) || (scroll == 0)) {
    	    if (_head.hasClass('fixed') == true) {
	        _head.removeClass('fixed');   
	        _bread.css('padding-top', '0');
	    }
        }
    	startPos = scroll;
    });
});

変数定義の部分では、下記のオブジェクトの割り当て、値の代入を行っています。

  • _window:Windowオブジェクト
  • _head:idが”site-header”であるオブジェクト(ヘッダー)
  • _bread:idが”breadcrumb”であるオブジェクト(パンくずリスト)
  • headHeight:ヘッダーの高さ
  • startPos:スクロール開始位置(スクロール量と比較してスクロールの方向を判断します)
  • scroll:スクロール量

処理はヘッダーを固定する処理とヘッダー固定を解除する処理に分かれています。

ヘッダーの固定は、上スクロールかつスクロール量がヘッダー高さより大きい場合に実行されます。

ヘッダー固定の解除は、下スクロールまたはスクロール量が0の場合に実行されます。

ヘッダー固定時およびヘッダー固定解除時の処理の詳細は下記のとおりです。

ヘッダー固定時
  • _headにclass “fixed”を追加。
  • _breadの”padding-top”に”headHeight”をインラインで設定。
  • 上記の処理は_headにclass “fixed”が設定されていない場合のみ実行されます。
ヘッダー固定解除時
  • _headのclass “fixed”を削除。
  • _breadの”padding-top”に0をインラインで設定。
  • 上記の処理は_headにclass “fixed”が設定されている場合のみ実行されます。

上記のコードをmkyScript.jsに保存します。

2. jQueryファイルの読み込み

mkyScript.jsを読み込ませるために、「Twenty Twenty子テーマ作成」で作成したfunctions.php内の関数theme_enqueue_styles()に下記のコードを追加します。

// jQuery読み込み
wp_enqueue_script( 
    'jquery', 
    'https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js', 
   array(), 
   '3.3.1' 
);
wp_enqueue_script( 
    'mky-script', 
    get_stylesheet_directory_uri() . '/mkyScript.js',
    array(),
    filemtime( get_theme_file_path( '/mkyScript.js' ) )
);

mkyScript.jsだけだと動作せず、「”jQuery”が未定義」とのエラーが発生していたので、mkyScript.jsの前にjQuery本体を読み込むようにしました。

mkyScript.jsを読み込む際は、「Twenty Twenty子テーマ作成」で子テーマのstyle.cssを読み込む際にしたようにファイルの更新時刻を取得するようにしました。

「スクロール時にナビゲーションメニューを固定する」でも同じようにしておけば表示がガタつくといった現象は発生しなかったかもしれません。

今となっては確認できませんが…

3. CSSの設定

class “fixed”追加時のヘッダーのCSSを設定します。

/* ヘッダーのスクロール対応 */
#site-header.fixed {
    position: fixed;
    top: 0;
    width: 100%;
    background: transparent;
    z-index: 100;
}

今回もpositionを”fixed”、topを”0″とすることでヘッダーをトップ位置に固定し、backgroundを”transparent”とすることで背景を透明にしています。

z-indexは元々2が設定されていました(Twenty Twentyの初期設定?)。そのままでもPCでは問題なかったのですが、スマホでは画像がヘッダーのコンテンツより上をスクロールしていくので100に変更しました。

以上が今回の修正内容です。

要求仕様2(下スクロール後ヘッダーの一部が表示されている状態から上スクロールする場合はヘッダーを固定しない)については、マウスホイールでスクロールする場合には確認できないかもしれません。確認される場合は、スクロールバーの下矢印を1回だけクリックしてから上スクロールするか、スクロールバーをつかんだ状態で少しずつスクロールしてみてください。

ヘッダー固定の第2条件を(startPos > headHeight)にしても良さそうですが、その場合ヘッダーの一部がまだギリギリ表示されている状態からの上スクロールでもヘッダーが固定され違和感があったので、(scroll > headHeight)にしています。

要求仕様4(ヘッダー固定時はヘッダーの背景を透明にする)については、やってはみたものの文字が重なると見づらいと感じているので、今後変更するかもしれません。

最後までお読みいただきありがとうございました。