[css]スマホ対応のスクロール禁止ギミック

自作できるのは嬉しい

そもそもの話

詳細はほぼ覚えてないんだけど、以前調べたときはiPhoneに効かないみたいな条件付ばっかりで、スマホに対応できんなら意味ないわっていう。

グローバルナビを設置するにはスマホのデザインだと狭すぎるのでアイコンをタップしたら表示みたいなのがよくある。それは普通にスライドさせて表示させたり、ページの上のレイヤーに固定表示したりで様々ある。

それだけの認識でもって好みのデザインを採用すればいいんだけど、ナビゲーション項目が多くて画面をぶち抜いた場合はどうすんのって話になる。position:fixed;とかで固定表示すると表示領域というか要素の高さが限られるんで、入れ子を噛ませてoverflow-y:auto;とかでスクロールできるようにしましょうねって対策を取る。それもまあ想定内。

oveflowで要素内のスクロールができました、良かったねで済まない。
ページ自体のスクロールのことがある。
ナビのスクロールが終わったらページ側のスクロールが始まるみたいな、二重構造だからしょうがないけど操作としては望まれていない動作がある。

だから、特定のコンテンツだけをスクロールする(=ページ自体をスクロールしない)状態がひつようになる。

で、それは調べ方が悪かったのもあるかもしれないけど、スマホで実現したいのにスマホが除外されるっていう本末転倒な話がありましたよっていうね。

参考

Webページでスクロールできないようにする - CSS Positionプロパティを利用 - CSS Tips

メチャクチャ簡単だった。

方法

今までになく感動したので引用は放棄します。
URLに飛んで確認して下さい。

Webページでスクロールできないようにする - CSS Positionプロパティを利用 - CSS Tips

classとかidでもってギミックを用意してjsで付与タイミングを操作したら完了。

最後に

調べてた当時はスクロール禁止はjsでどうのこうのみたいなのが多かったんです。手間がかかる上に条件付きってなんだよって話で。自分の無知もあるけど出来合モノのプラグインじゃないと結局導入できなかった。

それがCSSだけで実現できたってのが本当に嬉しい。
めっちゃスマート。
レスポンシブもほぼCSSで組み上げて、jsではclassの付与だけみたいな感じに進めてたんで今回のテーマにもあってた。最高。

ついでに

これを導入したときに問題が一つある。

ページをある程度スクロール下状態でメニューを表示してメニューを閉じたらページの一番初めに戻っちゃう。cssの設定的に道理に適った動作なんだけどユーザーはびっくりするし、使いづらいなってなる。

ページの先頭にメニューボタンを設置する場合は無視していい。

メニュー表示のボタンをposition:fixed;で設置するとかしてる場合はページの表示位置を維持するためのギミックを増やす必要がある。

ということで、以下の動作を追加する。

メニュー表示時
・表示領域の座標を取得
・座標をマイナス値に変換してbodyのtopに指定

メニュー非表示時
・bodyのtopの値をマイナス値にしてwindowの表示座標に指定
・bodyのtopを削除

座標を変数で格納できたらいいんだけどね。ボタンクリック時がトリガーだから都度リセットされちゃうんで、どっかでリレーさせて引っ張る必要がある。

$(function(){
    //header
    $('#btn_hNav').on('click',function(){
        var scrollHeight = window.pageYOffset;
        $(this).toggleClass('active');
        $('header .nav').fadeToggle();
        $('body').toggleClass('noscroll');
        if($('body').hasClass('noscroll')){
            $('body').css('top',-(scrollHeight));
        }else{
            var scrollPosition = $('body').css('top').replace(/[^0-9]/g, '');
            $(window).scrollTop(scrollPosition);
            $('body').css('top','');
        }
    })
    $(window).on('load resize', function(){
        w = $(window).innerWidth();
        if(w < 767.98){
            $('header .nav').hide();
        }else{
            $('#btn_hNav').removeClass('active');
            $('header .nav').show();
            $('body').removeClass('noscroll');
        }
    })
})

htmlタグとかclassとかはイメージができるものをつけてるんで、そこから想像してほしい。

コメント

タイトルとURLをコピーしました