このように、最初ヘッダートップにあってスクロールすると消えるけど、再び上からにゅるっと出てくるメニューバー。
メニューバーはいつもなんか適当に作ってたので、この機会にちゃんとまとめてみます。
まずはHTML
<ul class="header-nav js-header-nav"> <li><a href="#">Main</a></li> <li><a href="#News">News</a></li> <li><a href="#price">Price</a></li> <li><a href="#access">Access</a></li> <li><a href="#contact">Contact</a></li> </ul>
CSS
.header-nav { /* liアイテムを横並び */ display: flex; /* ul全体の幅・高さ */ width: 100%; height: 100px; background: pink; } .header-nav li { /* メニュー名を左右中央寄せ */ text-align: center; /* li box の高さをulに合わせる */ line-height: 100px; width: calc(100% / 5); } .header-nav li a{ /* リンクをブロックいっぱいに */ display: block; color: #000; }
CSSもシンプルなんですが、
li の高さをul に合わせて、かつ垂直に中央にしようとすると、
heightを100%に指定したりline-height/heightを同値で指定したりすると
望むようになってくれなくて困りました。。
とりあえず上記のCSSで各li の幅いっぱいにリンクが押せるメニューバーが出来上がりです。
jQuery
$(function() { let headNav = $('.js-header-nav'); //scrollしたとき $(window).on('scroll', function () { //現在の位置が200pxより大きいかつ、クラスfixedが付与されていない(false)時 if($(this).scrollTop() > 200 && headNav.hasClass('fixed') == false) { //headerの高さ分上に設定(上から降りてくるようにするため) headNav.css({top: '-100px'}); //クラスfixedを付与 headNav.addClass('fixed'); //位置を0に設定。1秒かけてアニメーションでにゅるっと降りてくる headNav.animate({top: 0},1000); } //現在の位置が200px以下かつ、クラスfixedが付与されている時にfixedを外す else if($(this).scrollTop() <= 200 && headNav.hasClass('fixed') == true){ headNav.removeClass('fixed'); } //場合によってフロートナビゲーションの残像が残ることがあったので追記。後で少し説明します。 else if($(this).scrollTop() <= 200) { headNav.removeClass("fixed"); } }); });
ちょっと長いですが、最初のブロックでは一定までスクロールしたときの
「にゅるっと出てくる」アニメーションの位置・動きを指定しています。
jQueryで「fixedクラス」を付与し、top:0の指定もできましたが、後ほどcssへも「.fixed」のスタイルを追記します
そして後ろのブロックでは、スクロールが一定まで満たない状態の指定をしています。
通常ハイフンでつなぐようなプロパティをanimate関数へ指定する時は、
キャメルケースで書くそうです。
fontSize backgroundColor …等
.fixed へスタイル指定
.fixed{ position: fixed; /* top: 0; ←はjQeryで指定済み*/ }
positionを指定しないとtop:0 だけでは思うようにならないので、
cssでposition:fixed を指定します。
とりあえずこれで上からにゅるっと降りてくるメニューバーが完成です!
上から降りてきたらCSSを変えたい
こういう感じで、上からスライドダウンしてきた時に見た目を変えたい!
というわがまま要望があった場合も追記するだけでいけます。
/* ヘッダーナビがスクロールでダウンしてきたとき */ .fixed{ position: fixed; } .header-nav.fixed { background: rgba(255, 99, 71, .7); } .fixed .changeColor { background: yellow; }
先ほどの.fixedはそのままにして、
.fixedがついてる場合の.header-nav(ul全体)の背景色を指定。
CSSを上書きしてあげます。
おまけとして、.fixedがついてるときの1つめのliアイテムにも変化をつけてあげました。
そのためにあらかじめ1つめのliにclass=”changeColor”を追記してあります。
ナビメニューの下側にシャドウをつけたい場合は
フロートナビゲーションの残像が・・・?
さきほど、後で説明しますと書いたjQueryの最後のコードですが、
トップ固定ナビゲーションとフロートナビゲーションの位置が違うページを作っていて、
たとえば、トップ固定ナビはヘッダーの上から100pxの位置。フロートナビはfixedのtop:0;だったとします。
パッと見の挙動は大丈夫なのですが、フロートナビがちょうど出現するくらいのぎりぎりのところでヘッダーにスクロールして戻ったりすると
フロートナビの残像がtop:0;の位置に謎に残っていたことがありまして。
とりあえず最後のコードを追記したら解決しました。
無くても動く場合も多いと思いますので、環境によって修正ください。
今思うと、if 、else ifの条件が甘いんですかね・・・?ifとelseだけでもいいような気がしてきましたが、それはまた今度考えます。。
最終的なコード
html
<ul class="js-header-nav header-nav"> <li><a class="changeColor"href="#">Main</a></li> <li><a href="#">News</a></li> <li><a href="#price">Price</a></li> <li><a href="#access">Access</a></li> <li><a href="#contact">Contact</a></li> </ul>
css
.header-nav { /* liアイテムを横並び */ display: flex; /* ul全体の幅・高さ */ width: 100%; height: 100px; background: pink; } .header-nav li { /* メニュー名を左右中央寄せ */ text-align: center; /* li box の高さをulに合わせる */ line-height: 100px; width: calc(100% / 5); } .header-nav li a{ /* リンクをブロックいっぱいに */ display: block; color: #000; } /* ヘッダーナビがスクロールでダウンしてきたとき */ .fixed{ position: fixed; } .header-nav.fixed { background: rgba(255, 99, 71, .7); } .fixed .changeColor { background: yellow; }
jquery
これは先ほどと全く同じですが、一応
$(function() { let headNav = $('.js-header-nav'); //scrollしたとき $(window).on('scroll', function () { //現在の位置が200px以上かつ、クラスfixedが付与されていない(false)時 if($(this).scrollTop() > 200 && headNav.hasClass('fixed') == false) { //headerの高さ分上に設定(上から降りてくるようにするため) headNav.css({top: '-100px'}); //クラスfixedを付与 headNav.addClass('fixed'); //位置を0に設定。1秒かけてアニメーションでにゅるっと降りてくる headNav.animate({top: 0},1000); } //現在の位置が200px以下かつ、クラスfixedが付与されている時にfixedを外す //(スクロールアップでも消えるように) else if($(this).scrollTop() < 200 && headNav.hasClass('fixed') == true){ headNav.removeClass('fixed'); } //必要に応じてつける else if($(this).scrollTop() <= 200) { headNav.removeClass("fixed"); } }); });
こんな感じでできました!
お疲れ様です〜
☆参考サイト OKULOG様
CodePenも使ってみました!!
※スライドダウン時のbackground透過とboxshadowも加えているので、
上記のコードとは微妙に異なります。
See the Pen
上からにゅるっとメニューバー by hiro (@hiro555)
on CodePen.