サイドバーに表示している広告や目次などで、画面をスクロールしても画面の上とかに固定されて追従してくるものってありますよね?

ワードプレスで使うテーマによってはそうした動作をするサイドバー専用のウイジェットが用意されている場合もありますが、私が使っている賢威8にはないようです。

そこでここではテーマにそうしたウイジェットが用意されてない場合、CSSで簡単に「スクロールしても固定で追従する」方法とそのポイントを解説します。

このブログでもサイドバーの一番下に記事の目次をスクロールにより固定/追従で表示してますので、実際の動作はそちらを参考までに見てみてくださいね。

使用するCSS

サイドバーに限らず、あるところまでスクロールすると上部に固定されて追従してくる、というのは今ではCSSで簡単に実現できます。

  • セレクタ
    • スクロールして上部に固定したい要素の ID や クラスを指定
  • position: -webkit-sticky;
    • これがないとSafari では動作しないようだ
  • position: sticky;
    • スクロールすると固定・追従するCSS
  • top: 50px;
    • 上部からどれほど離れた位置に固定されるか数値で指定
    • 実際に動作確認した上で数値を調整してみてください

たったこれだけで実現できちゃうんですね(驚き!)

  • ※)簡単なデモ
  • 実はここの見出し「使用するCSS」にこの「position: sticky;」を設定してます。
  • 簡単なデモですが、スクロールして固定・追従しているのが分かるでしょうか?
  • 他の見出しには設定せず、ここだけに設定してます

サイドバーの要素に適用

サイドバーにウイジェットを配置

CSSのコードは非常にシンプル!

これでスクロールしても固定・追従する目次を作れるね!と、サイドバーの一番下に目次のウイジェットを置いてみます。

  • ※)補足
    • テーマによっては元々この「TOC+」のウイジェットが入っている場合があるので、今回の例のように目次をサイドバーに固定・追従表示させたい!という場合には、まずはウイジェット一覧の中に目次表示用のウイジェットががあるか探してみてください

実際にいくつか記事を表示して確認してみると、サイドバーの下にしっかり目次が表示されてます。(やったね!)

続いてCSSを設定

これだけでは勿論スクロールすると上の方に消えて行ってしまうので、早速さきほどのCSSを設定します。

先ほど見たCSSコードにある「セレクタ」は、スクロールして上部に固定したい要素の ID や クラスを指定しますが、このブログのサイドバーにある目次の場合、要素のid が「#toc-widget-2」なので、以下のCSSを設定することになりますね。

そしてドキドキしながらスクロールさせると...上部に固定せずに上の方にスクロールして消えて行く(笑)

position: sticky のふるまいを確認

「position: sticky;」はしっかり設定しているのに、なぜ固定・追従されずにスクロールしていってしまうのか。

調べてみると、「position: sticky;」で指定した要素は、その親の要素内で固定・追従される(つまり親要素の範囲内でしか動けない)、という仕様になっているからのようです。

この図で見るように、スクロールすると固定して追従する要素は、それを囲む親の要素内でしか移動ができない。

ということから、下の方に隙間がない場合では、スクロールしていくと下に動くスペースがないため普通にスクロールして消えて行ってしまう、ということになりますね。

実際賢威8のHTMLとCSSの構成がどうなっているか見ると以下の通り。

賢威8では②の記事と③のサイドバーは float で左右に並べられている、という構成になってますが、単に float だけが指定されている場合、サイドバーの縦方向の高さは固定で、②の記事が長くなってもサイドバーの縦方向の高さは固定のままで長くなりません。(つまりサイドバーはサイドバーに含まれる要素分の高さしかない)

こうなると、一番下の要素④(今回固定・追従させたい目次)に「position: sticky;」を設定しても、その下に動く領域がないので、結果としてスクロールすると固定・追従せずに普通に上の方にスクロールして消えて行ってしまう、ということになります。

ということから、④(目次)の要素をスクロールしても固定・追従させるには、サイドバーを記事の高さにそろえて(記事の高さと同じ高さに伸ばして)下に動くスペースを空ける必要がありますね。

サイドバーの高さを記事と同じにする

サイドバーを記事の高さとそろえるには、記事とサイドバーを囲む親要素に flex(display:flex;) を使えば解決します。

①の全体を囲む要素に display:flex; を設定。
すると、②の記事の長さに従って③のサイドバーの高さ方向も同じになる

賢威8では、①の全体を囲む要素や②の記事、③のサイドバーは以下のようなHTML構成になってます(グーグルクロームのデベロッパーツールで見たところ)

  • ① 全体を囲む要素: .keni-main_outer
  • ② 記事:#main
  • ③ サイドバー:#secondary

ということから①の「.keni-main_outer」に display:flex;を設定することになりますね(これでサイドバーの高さが記事とそろい、固定・追従させたい要素が下方向に動く領域が生まれる)

がしかし、これでもまだ目次が固定・追従しない!

overflowを排除せよ

非常に簡単便利な「position: sticky」ですが、実はこれ、指定する要素自体やその親、更に親の親といった祖先全てにについて、「overflow」「overflow-x」「overflow-y」プロパティの値が「visible」以外になっていると動作しないんだとか。

1つ1つ親をたどって調べるのはかなり面倒、ということで、jQuery を使って一括で対応する方法がありました。

今回スクロールで固定・追従させたい要素(目次)のセレクタは「div#toc-widget-2」なので以下の jQuery を設定します。

さぁ、これで流石に固定・追従するだろう!と見てみれば、ご覧いただいている通り、無事動作してますね。やったぜ!

レスポンシブ対応をしておく

最後の仕上げで、表示幅に対しての切り替えを入れておきましょう。

テーマは大抵の場合、横幅が小さい場合ではモバイル表示(スマホ表示)、ある一定以上に横幅が大きくなるとPC表示、と切り替わるようになってます。(どの画面サイズでも適切な表示になるように、いわゆるレスポンシブの対応が入っている)

この横幅による切り替わりを考えずに、単に以下のCSSを設定すると、モバイル表示でもPC表示がされてしまい(スマホで見てもサイドバーが横に出てきて)非常に窮屈で小さい表示になってしまいます。

どの横幅で切り替わるかはテーマによりますが、賢威8の場合、768pxより小さい場合はモバイル表示、768px以上でPC表示に切り替わるように設定されてますので、それに合わせておけばバッチリ。

ということから、私のブログの場合では(賢威8の場合では)、768px以上でのみ(PC表示時のみ)今回の対応をする、として、CSSは以下のようにしておきます。

こうしておけば、PC表示の時だけサイドバーの目次が固定・追従表示になり、モバイル表示ではテーマの設定に従って表示される、となっていい感じです。

モバイル表示では目次を非表示

最後におまけですが、サイドバーの目次表示に限っては、モバイル表示で必要ないかも、とも思ったりします。

というのも、検索して訪れた人がスマホで記事を見て下の方にスクロールしていくところを考えれば、

  • 1)まず記事をスクロールしながら読む(スマホで読む)
  • 2)記事の後はサイドバーの内容を目に入る(人気記事や新着記事などサイドバーにつけている内容が表示される)
  • 3)すると最後にまた記事内容に関連する目次が表示される

と、なにか振出しに戻る的な感じがないでもない。(あれ?またいきなり記事の内容になった、みたいな。^-^;))

ユーザビリティ的に見た時、モバイル表示ではサイドバーの目次は非表示にした方が良いかも、という場合には、CSSにちょっとした工夫を入れておくのが良いかもしれません。

上のCSSコードについて、まず以下の部分でモバイル表示時は要素(目次)を非表示に設定。(要素に対して「display: none;」を設定)

PC表示(賢威8の場合は768px以上)では、要素(目次)を表示するために以下の部分に「display: block;」を設定

こうしておけば、モバイル表示で最後に表示される目次の違和感はなくなるかもしれません。

今回のポイント

  • 要素の固定・追従表示は「position: sticky;」を使えば簡単
  • 「position: sticky;」は親要素の中でのみスクロールによる固定・追従、といった動作ができる
  • 記事とサイドバーの高さがそろってないテーマでは「display:flex;」を使う高さがそろうかも(賢威8はそれでできた)
  • 「position: sticky;」は、親や祖先の要素の「overflow」「overflow-x」「overflow-y」プロパティが「visible」(初期値)以外になっていると動作しない(jQueryを使うと簡単に対応できる)

今回はサイドバーの目次について固定・追従するようにしてみましたが、これは目次に限らず色々なところで活用できます。

よくあるのがサイドバーの一番下に広告を表示し、それがスクロールしても固定・追従表示されるというもの。

他にもたとえば本文中に縦に長い表がある場合、先頭の見出し行を固定・追従にすると、記事をスクロールしながら見ても、どの列が何の項目かが分かりやすくなりますね。

CSSでの実現以外にも、jQueryを使うやり方もありますが、それはまた別記事で紹介したいと思います。

またネットビジネスで収益をあげたいが道筋が分からない、ブログやサイトで収益化するにはどうしたらよいか分からない、という場合には、以下のメルマガにも登録してみてくださいね。

早期退職して海外で奮闘する JIN のメールマガジン

時間や場所に縛られず稼いだJINが教える

~ 最短最速で月収10万円を手に入れる方法 ~

苗字(必須)

隣のあの人にも、思わず教えたくなる秘密

配信停止は、いつでもできます

お預かりした情報は保護されます

迷惑メールは一切配信されませんので、ご安心くださいね