Written by Toshiki

スクロールしたら画面上部に追従ヘッダーを表示する方法(jQuery使用)

JavaScript Web制作

こんにちは、トシキです。
今回は「スクロールしたら画面上部に追従ヘッダーを表示する方法」について解説していきます。

本記事の内容

スポンサードサーチ

①スクロールしたら画面上部に追従ヘッダーを表示する方法(jQuery使用)

上記のような挙動になります。
JavaScriptバージョン(脱jQuery)はこちら↓

See the Pen スクロールしたら画面上部にスライド表示されるメニュー by tosshii (@totototosshii) on CodePen.

1-01. HTML


<header class="ly_header">
  <div class="ly_header_inner">
    <nav class="bl_headerNav">
      <ul class="bl_headerNav_list">
        <li><a href="#1">ヘッダーメニュー01</a></li>
        <li><a href="#2">ヘッダーメニュー02</a></li>
        <li><a href="#3">ヘッダーメニュー03</a></li>
        <li><a href="#4">ヘッダーメニュー04</a></li>
      </ul>
    </nav>
  </div>
  <div class="ly_fixedNav" aria-hidden="true" aria-label="追従ヘッダー">
    <nav class="bl_fixedNav">
      <ul class="bl_fixedNav_list">
        <li><a href="#1">追従メニュー01</a></li>
        <li><a href="#2">追従メニュー02</a></li>
        <li><a href="#3">追従メニュー03</a></li>
        <li><a href="#4">追従メニュー04</a></li>
      </ul>
    </nav>
  </div>
</header>

<section class="ly_cont">
  <h2>メインコンテンツ</h2>
</section>

header内の.ly_header_innerが元々表示されているエリアで、.ly_fixedNavがスクロールしたら表示されるエリアになります。

1-02. CSS


/* ヘッダー */
.ly_header,
.ly_fixedNav {
  padding-block: 1rem;
}

.ly_header {
  background-color: #DDD;
}

.ly_header_inner,
.bl_fixedNav {
  padding-inline: 1rem;
}

.ly_fixedNav {
  background-color: #B6E1B5;
  position: fixed;
  inset-block-start: -100%;
  inset-inline-start: 0;
  z-index: 30;
  inline-size: 100%;
  transition: inset-block-start .4s, visibility .4s;
  visibility: hidden;
}

.ly_fixedNav.is_active {
  inset-block-start: 0;
  visibility: visible;
}

.bl_headerNav_list,
.bl_fixedNav_list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;

  a {
    display: inline-block;
    line-height: 1.5;
    padding-inline: 1em;
  }
}
/* ヘッダーここまで */

/* メインコンテンツ */
.ly_cont {
  background-color: lightblue;
  text-align: center;
  block-size: 1000px;
  padding-block-start: 60px;
}

.ly_fixedNavについて

  • 追従ヘッダーは初期状態で画面外(上部)に配置するため、inset-block-start: -100%;を指定。
  • スクロールに応じて上からスライドインするよう、transitionを適用。
  • 初期状態では画面外にあるため、visibility: hidden;を指定してフォーカスが当たらないようにする。
  • .ly_fixedNav.is_activeには、追従ヘッダーを表示するためのスタイルを記述。

フォーカスが有効な場合は、Tabキーを押すとリンクを囲った状態になります。

1-03. jQuery


// 追従ヘッダーの関数
const showFixedHeader = () => {
  const scrollTop = $(window).scrollTop();
  const headerHeight = $('.ly_header').outerHeight();
  const fixedNav = $('.ly_fixedNav');
  const isHeaderVisible = scrollTop < headerHeight;
  fixedNav.toggleClass('is_active', !isHeaderVisible).attr('aria-hidden', isHeaderVisible);
}

// 画面をスクロールをしたら発火
$(window).on('scroll', () => {
  showFixedHeader();
});

スクロールしていき.ly_headerの高さを過ぎたら、.ly_fixedNav.is_activeクラスを付与し、area-hiddenの値を変更する内容になっています。


const scrollTop = $(window).scrollTop();

$(window).scrollTop()で現在のスクロール位置(ページの一番上からのスクロール量)を取得。


const headerHeight = $('.ly_header').outerHeight();

通常ヘッダー(.ly_header)の高さを取得します。outerHeight()を使うことで、paddingborderを含めた高さを取得できます。


const fixedNav = $('.ly_fixedNav');

追従ヘッダー(.ly_fixedNav)の要素を取得します。


const isHeaderVisible = scrollTop < headerHeight;

scrollTop < headerHeightの条件を使って、スクロール位置が通常ヘッダーの高さより小さいかどうかを判定します。
スクロール量が少なく、まだ通常ヘッダーが画面内に表示されている場合はtrue、逆にスクロール量が通常ヘッダーの高さを超えて画面外へ消えた場合はfalseとなり、その値がisHeaderVisibleに代入されます。


fixedNav.toggleClass('is_active', !isHeaderVisible)

isHeaderVisibleの値に応じて、fixedNav(追従ヘッダー)に.is_activeの追加と削除を行います。
!isHeaderVisible!は否定演算子と呼ばれ、isHeaderVisibleの値を反転させるためのものです。
つまり、isHeaderVisibletrueならfalseに、falseならtrueになります。

  • isHeaderVisibletrue(通常ヘッダーがまだ見えている状態)の場合、.is_activeを削除し、追従ヘッダーを非表示にする。
  • isHeaderVisiblefalse(スクロールが進み、通常ヘッダーが見えなくなった状態)の場合、.is_activeを追加し、追従ヘッダーを表示する。

.attr('aria-hidden', isHeaderVisible);

aria-hidden属性を、isHeaderVisibleの値に基づいて設定します。
attr() は、指定した属性の値を取得したり設定したりするためのメソッドです。ここでは、aria-hidden属性を設定しています。

  • isHeaderVisibletrueの場合、.attr('aria-hidden', 'true')としてaria-hidden="true"を設定し、スクリーンリーダーに対して追従ヘッダーを「非表示」として認識させます。
  • isHeaderVisiblefalseの場合、.attr('aria-hidden', 'false')としてaria-hidden="false"を設定し、スクリーンリーダーに対して追従ヘッダーを「表示」と認識させます。

②まとめ

今回のポイント

  • header内には、元々表示されるエリアとスクロール時に表示されるエリアをそれぞれマークアップ。
  • aria-hidden属性は逆に指定しないように気を付ける(trueが非表示状態、falseが表示状態)。
  • スクロール時に表示させるエリアのスタイルは、初期状態でinset-block-startを使い画面外に配置し、visibilityの指定も忘れずに行う。

以上になります。

この記事が役に立ったら、応援してくれると嬉しいです! 投げ銭で応援する

人気記事Webサイトにフォントサイズ変更ボタンを実装する方法(jQuery使用)

人気記事【脱jQuery】スクロールしたら画面上部に追従ヘッダーを表示する方法