Written by Toshiki

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

JavaScript Web制作

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

本記事の内容

スポンサードサーチ

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

上記のような挙動になります。

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

01. HTML




<header class="ly_header">
  <nav class="bl_headerNav" aria-hidden="false" aria-label="ヘッダーメニュー">
    <ul class="bl_header_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>
  <nav class="ly_fixedNav" aria-hidden="true" aria-label="追従メニュー">
    <ul class="bl_fixedNav_list">
      <li><a href="#5">追従メニュー01</a></li>
      <li><a href="#6">追従メニュー02</a></li>
      <li><a href="#7">追従メニュー03</a></li>
      <li><a href="#8">追従メニュー04</a></li>
    </ul>
  </nav>
</header>

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

<header>直下には2つの<nav>があり、.bl_headerNavクラスの方が元々表示されているメニューのエリア。
.ly_fixedNavクラスの方が、スクロールしたらスライドインしてくるエリアになります。

02. CSS




/* SCSS
ヘッダー部分 */
.ly_header {
  padding: 30px;
  background-color: #ddd;
}

.ly_fixedNav {
  position: fixed;
  top: -100%;
  left: 0;
  width: 100%;
  padding: 30px;
  background-color: #b6e1b5;
  transition: top .8s, visibility .8s;
  visibility: hidden;
}

.bl_header_list,
.bl_fixedNav_list {
  display: grid;
  column-gap: 1em;
  grid-auto-columns: 1fr;
  grid-auto-flow: column;
  max-inline-size: max-content;
  margin-inline: auto;
  li {
    display: grid;
    place-items: center;
  }
  a {
    line-height: 1.5;
    padding: 1em;
  }
}
/* ヘッダー部分ここまで */

/* メインコンテンツ */
.ly_cont {
  height: 2000px;
  background-color: lightblue;
  text-align: center;
  padding: 30px 0;
}

.ly_fixedNavについて

  • 初期状態は非表示にしたいので、top: -100%;で画面外上部へ。
  • スクロールしたら上からスライドインでアニメーションさせたいので、transitionを指定。
  • 初期状態は画面外にいるので、Tabキーを押してもフォーカスが当たらないように、visibility: hidden;を指定。

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

03. jQuery




// 追従メニューの関数
const FixedNav = () => {
  const scroll = $(window).scrollTop();
  const header = $('.bl_headerNav');
  const fixed = $('.ly_fixedNav');
  const isHeaderVisible = header.height() >= scroll - 60;
  header.css('visibility', isHeaderVisible ? 'visible' : 'hidden').attr('aria-hidden', !isHeaderVisible);
  fixed.css({'top': isHeaderVisible ? '-100%' : '0', 'visibility': isHeaderVisible ? 'hidden' : 'visible'}).attr('aria-hidden', isHeaderVisible);
}

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

スクロールしていき.bl_headerNavの高さを過ぎたら、.bl_headerNav.ly_fixedNavそれぞれのcssと、area-hiddenの値を変更する内容になっています。
.css()メソッドではvisibilitytopの値を変更。
.attr()メソッドではaria-hidden属性を取得して、属性値を変更しています。



const isHeaderVisible = header.height() >= scroll - 60;

header.height().bl_headerNavの要素の高さを取得し、scroll - 60は現在のスクロール位置から60px引いた値になります。
スクロール位置が60px未満の場合はtrue、それ以上ならfalseisHeaderVisibleに代入されます。
-60はスライドインのタイミングが思ったより遅い、もしくは早かったりしたら適宜調整してください。



header.css('visibility', isHeaderVisible ? 'visible' : 'hidden').attr('aria-hidden', !isHeaderVisible);

!isHeaderVisible!は否定演算子で、isHeaderVisibletrueならばfalse、逆にfalseならばtrue!isHeaderVisibleに入ります。
isHeaderVisible ?〜の部分は三項演算子で条件分岐しています。

クリックで拡大できます↓

04. 「aria-hidden」と「aria-label」属性

アクセシビリティを意識して、WAI−ARIA(ウェイアリア)を使用してみました。
今回使用したものを軽く解説。

aria-hidden属性

true(非表示)/false(表示)で要素の状態を示します。
trueにすると非表示の状態となり、スクリーンリーダーで読み上げられなくなります。

aria-label属性

その要素に任意のテキストを指定。
画面上ではそのテキストは見えないけど、スクリーンリーダーでは読み上げたい場面で使用します。
今回のサンプルでは、aria-labelに「ヘッダーメニュー」と記述しているのでそれを読み上げてくれます。

05. まとめ

今回のポイント

  • <header>内には元々表示させる用と、スクロール時に表示させる用の2ソースの<nav>でマークアップ。
  • aria-hidden属性は逆に指定しないように気を付ける(trueが非表示状態で、falseが表示状態)。
  • スクロール時に表示させる用のスタイルは、初期状態はtopで画面外に。visibilityの指定も忘れずに。

以上になります。

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

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