ヘッダー・ナビゲーションを固定表示させるアイデア5つ

ヘッダー・ナビゲーションを固定表示させるアイデア5つ

スクロールしても固定表示されるヘッダーは珍しくありませんが、その方法はいくつかあります。今回は5つのパターンでサンプルを作成してみました。

最初から固定表示

基本なので言わずもがなですが一応。単なる固定表示ならCSSの「position: fixed;」だけです。簡単ですね。

HTML

<header class="site-header">
    <h1 class="site-logo"><img src="images/logo.png" alt="WEBDESIGNDAY"></h1>
    <nav class="gnav">
        <ul class="gnav__menu">
            <li class="gnav__menu__item"><a href="">About</a></li>
            <li class="gnav__menu__item"><a href="">Works</a></li>
            <li class="gnav__menu__item"><a href="">Recruit</a></li>
            <li class="gnav__menu__item"><a href="">News</a></li>
            <li class="gnav__menu__item"><a href="">Contact</a></li>
        </ul>
    </nav>
</header>
<div class="hero"><img src="images/hero.jpg" alt="hero"></div>
<div class="content">
    <!--省略-->
</div>
<footer class="site-footer">
    <p class="copyright">@2017 WEBDESIGNDAY</p>
</footer>

CSS

body{
    background: #81bcd8;
}
.site-header{
    background: #fff;
    display: flex;
    padding: 60px 20px;
    position: fixed;
    justify-content: space-between;
    width: 100%;
}
.site-logo img{
    height: 20px;
    width: auto;
}
.gnav__menu{
    display: flex;
}
.gnav__menu__item{
    margin-left: 20px;
}
.gnav__menu__item a{
    color: #333;
    text-decoration: none;
}
.hero{
    max-height: 500px;
    overflow: hidden;
}
.hero img{
    height: auto;
    width: 100%;
}
.content{
    line-height: 1.6;
    margin: 0 auto;
    padding-top: 100px;
    width: 800px;
}
.content p{
    margin-bottom: 40px;
}
.site-footer{
    background: #333;
    padding: 80px 0;
}
.copyright{
    color: #fff;
    font-size: 12px;
    text-align: center;
}

最初から固定表示、特定位置までスクロールでサイズ・色を変える

windowのスクロールイベントを受け取り、特定の位置までスクロースしたらヘッダーにクラスをつけてCSSを変更します。

HTML

 HTMLは変更なしです。

CSS

.site-header{
    background: rgba(255,255,255,0.5);
    display: flex;
    padding: 60px 20px;
    position: fixed;
    justify-content: space-between;
    transition: .5s;
    width: 100%;
}
.site-header.transform{
    background: rgba(255,255,255,0.9);
    padding: 20px;
}

2行目

変更後の違いをわかりやすくするためと、メインの画像の邪魔をしないように背景色を透過させています。

11行目

特定位置までスクロールするとjQueryで「transform」クラスをつけますので、スタイルを変えています。

jQuery

var _window = $(window),
    _header = $('.site-header'),
    heroBottom;
 
_window.on('scroll',function(){
    heroBottom = $('.hero').height();
    if(_window.scrollTop() > heroBottom){
        _header.addClass('transform');   
    }
    else{
        _header.removeClass('transform');   
    }
});
 
_window.trigger('scroll');

6行目

変数「heroBottom」にメイン画像エリアの高さを入れています。画像ですので、jQueryが読み込まれてすぐに変数に高さを入れようとすると正常な高さが取得できません。

ですので、スクロール時に高さを変数に入れています。

7行目

今回は、「メイン画像エリアの「.hero」の下までスクロールしたら」というのを条件判定にクラスをつけていきます。

途中から固定表示

HTML

<div class="hero"><img src="images/hero.jpg" width="1600" height="1200" alt="hero"></div>
<header class="site-header">
    <h1 class="site-logo"><img src="images/logo.png" alt="WEBDESIGNDAY"></h1>
    <nav class="gnav">
        <ul class="gnav__menu">
            <li class="gnav__menu__item"><a href="">About</a></li>
            <li class="gnav__menu__item"><a href="">Works</a></li>
            <li class="gnav__menu__item"><a href="">Recruit</a></li>
            <li class="gnav__menu__item"><a href="">News</a></li>
            <li class="gnav__menu__item"><a href="">Contact</a></li>
        </ul>
    </nav>
</header> 
<div class="content">
    <!--省略-->
</div>
<footer class="site-footer">
    <p class="copyright">@2017 WEBDESIGNDAY</p>
</footer>

メイン画像とヘッダーの順番を入れ変えました。

CSS

.site-header{
    background: #fff;
    display: flex;
    padding: 20px;
    position: absolute;
    justify-content: space-between;
    width: 100%;
}
.site-header.fixed{
    position: fixed;
    top: 0;
}

5行目

「position: absolute;」にしておくのがポイントです。こうしておかないと固定表示にした途端、下のコンテンツがヘッダーの高さ分上にカクっとずれてしまいます。

10,11行目

jQueryで「.fixed」クラスをつけますので固定表示にします。

jQuery

var _window = $(window),
    _header = $('.site-header'),
    heroBottom;
 
_window.on('scroll',function(){     
    heroBottom = $('.hero').height();
    if(_window.scrollTop() > heroBottom){
        _header.addClass('fixed');   
    }
    else{
        _header.removeClass('fixed');   
    }
});
 
_window.trigger('scroll');

15行目

スクロールをきっかけにしているので、途中までスクロールしている状態でリロードされた場合、スクロールイベントが発生しません。
ですので、「_window.trigger(‘scroll’);」でロード時に「スクロールしたよ」と通知しています。

あとは先ほどのサンプルとほとんど何も変わりません。つけるクラス名が「fixed」になっただけです。

途中からヘッダーを入れ替える

HTML

<div class="hero"><img src="images/hero.jpg" width="1600" height="1200" alt="hero"></div>
<header class="site-header">
    <h1 class="site-logo"><img src="images/logo.png" alt="WEBDESIGNDAY"></h1>
    <nav class="gnav">
        <ul class="gnav__menu">
            <li class="gnav__menu__item"><a href="">About</a></li>
            <li class="gnav__menu__item"><a href="">Works</a></li>
            <li class="gnav__menu__item"><a href="">Recruit</a></li>
            <li class="gnav__menu__item"><a href="">News</a></li>
            <li class="gnav__menu__item"><a href="">Contact</a></li>
        </ul>
    </nav>
</header> 
<div class="content">
    <!--省略-->
</div>
<footer class="site-footer">
    <p class="copyright">@2017 WEBDESIGNDAY</p>
</footer>
<div class="header-change">
    <h1 class="site-logo"><img src="images/logo-w.png" alt="WEBDESIGNDAY"></h1>
    <nav class="gnav">
        <ul class="gnav__menu">
            <li class="gnav__menu__item"><a href="">About</a></li>
            <li class="gnav__menu__item"><a href="">Works</a></li>
            <li class="gnav__menu__item"><a href="">Recruit</a></li>
            <li class="gnav__menu__item"><a href="">News</a></li>
            <li class="gnav__menu__item"><a href="">Contact</a></li>
        </ul>
    </nav>        
</div>

20行目

フッターの後に入れ替え用のヘッダー「header-change」を追加しました。

CSS

.site-header{
    background: #fff;
    display: flex;
    justify-content: space-between;
    padding: 20px;
    position: absolute;
    width: 100%;
}
.header-change{
    background: #333;
    display: flex;
    justify-content: space-between;
    padding: 20px;
    position: fixed;
    top: -63px;
    transition: .5s;
    width: 100%;
}
.header-change.show{
    top: 0;
}
.header-change .gnav__menu__item a{
    color: #fff;
    text-decoration: none;
}

「header-change」のスタイルを追加しています。

15行目

 ヘッダー高さだけ上に移動して隠しています。

jQuery

var _window = $(window),
    _header = $('.site-header'),
    headerChange = $('.header-change'),
    heroBottom;
 
_window.on('scroll',function(){     
    heroBottom = $('.hero').height();
    if(_window.scrollTop() > heroBottom){
        headerChange.addClass('show');  
    }
    else{
        headerChange.removeClass('show');
    }
});
 
_window.trigger('scroll');

9行目

クラスをつけるのが入れ替え用のヘッダーに変更になっただけであとは同じです。

下にスクロールで消えて上にスクロールで固定表示

HTML

HTMLはサンプル3と同じです。

CSS

.site-header{
    background: #fff;
    display: flex;
    justify-content: space-between;
    padding: 20px;
    position: fixed;
    top: 0;
    transition: .5s;
    width: 100%;
}
.site-header.hide{
    top: -63px;
}

12行目

こちらはクラスがついたら上に移動して隠します。

jQuery

var _window = $(window),
    _header = $('.site-header'),
    heroBottom,
    startPos,
    winScrollTop;
 
_window.on('scroll',function(){
    winScrollTop = $(this).scrollTop();
    heroBottom = $('.hero').height();
    if (winScrollTop >= startPos) {
        if(winScrollTop >= heroBottom){
            _header.addClass('hide');
        }
    } else {
        _header.removeClass('hide');
    }
    startPos = winScrollTop;
});
 
_window.trigger('scroll');

10・17行目

直前までのスクロール位置を「startPos」に入れて、それに対してスクロールが増えていれば下スクロール。そうでなければ上スクロールになります。

11行目

それだけだと下にスクロールし始めるとすぐに消えてしまうので今まで同様、メイン画像の下までスクロールしたら消えるように条件判定を追加しています。

Category&Tag