はてなブログのサイドバーをウィンドウ下に粘着

ページをスクロールしていきますと、メニューやサイドバーが、あるところでぴたっとページのトップに固定され、今度は逆にスクロールしますと再び追従し始めるサイトを見ることがあります。それをはてなブログでやってみます。



position:sticky

ウィンドウの上部に粘着させたい場合は、粘着させたい要素に position:stickytop:0 を指定すれば、簡単に粘着させられます。たとえば、はてなブログの場合でブログタイトルを上部に粘着させる場合は、

#blog-title{
  position: sticky;
  top: 0;
  // 場合によって以下が必要(値は適宜)
  z-index: 9999;
  background-color: #ffffff;
}

を指定すれば望みどおりになります。


f:id:ausnichts:20190902182339j:plain
Can i use ? CSS position:sticky

ただし、IEは対応していないようです。Polyfill というものもあるようですが、レイアウトに決定的な問題が発生しない、たとえば今やろうとしているサイドバーを粘着なんていうのは、粘着しなくなるだけですので無視してもいいと思います。


サイドバーをウィンドウ上部に粘着

サイドバーを粘着させるのは2カラムの場合になりますが、サイドバーの(親)要素 box2 が display:flexdisplay:grid の指定で配置されていないとうまくいきません。高さがコンテンツ側の要素 wrapper と同じじゃないとダメということでしょう。float ではうまくいきません。

そのうえで、 box2-inner に上と同じように指定すればサイドバーをウィンドウ上部に粘着されられます。


ただ、これではサイドバーがウィンドウサイズよりも長い場合は途中で止まったまま下が見られなくなってしまいます。


サイドバーをウィンドウ下に粘着

で、サイドバーがウィンドウサイズよりも長い場合に、順次スクロールしていき、サイドバーの下がウィンドウの下にきた時に粘着させる方法です。

Javascript が必要になります。


※使用、改変は自由ですが、転載はしないでください。

window.addEventListener('load', function(){
    // レスポンシブのテーマでメディアクエリを 768px で切っている場合
    if(window.matchMedia( '(min-width: 768px)' ).matches){
        const ch = document.documentElement.clientHeight;
        const sideBar = document.getElementById('box2-inner');
        const sh = sideBar.offsetHeight;
        sideBar.style.position = 'sticky';
        sideBar.style.top = -(sh - ch) + 'px';
    }
}, false);

これで、サイドバーがウィンドウ下に粘着します。

load イベントを使っているのは、サイドバーに新着情報など動的に挿入するモジュールがある場合にコンテンツの読み終わりを待たないとサイドバーの正しい高さが取得できないからです。

また、メディアクエリの値で切り分けている部分は、それぞれテーマのメディアクエリの値によって変更してください。

マージンを取りたい場合は、適宜数値をプラスするように追加してください。

これで、本文が長い場合でもサイドバーが空白になることはなくなります。