昔はJQuery使わないとできなかったことでも、最近はCSSを一行書くだけでできるようになったりと、色々便利なプロパティが増えてます。
今回はスクロールに応じてサイドバーの要素を固定させる、プロパティを使ってみようと思います。
便利すぎる position: sticky;
stickyってのは、ねっとりネバネバ、よくネットで嫌われる粘着質なヤツと言う意味。
つまり、画面に張り付きます。
しかも、スクロールに応じてイイ感じに。
ただ張り付くだけなら、position: fixed; でいいんですが、stickyは画面内では位置無指定、又はrelativeっぽく振る舞い、指定した位置方向に向かって要素が画面から外れようとしたタイミングでfixedに変化するイメージですね。
なんか言葉で説明するとわかりにくいですね。
position: sticky; の使い方
必要なのは2行のコードのみ!
.sticky { position: -webkit-sticky; position: sticky; top: 10px; }
「3行書いてるやんけ!いや、むしろ全部で5行やんけ。」って言うツッコみはなしでお願いします。
上記コードを書いて、サイドバーの固定させたい要素にクラス名 “sticky” を振るだけでOK。
めっちゃ簡単です。
top方向へ要素が外れようとしたときに、ビューの淵から10pxのところにsticky要素を固定(fixed)します。top方向以外への要素のはみ出しは固定されないのがposition: fixed;との大きな機能の違いですね!
sticky要素が素通りする
と、まぁここまでググって見つけた情報なんですが、このサイトに適用してみたところ、sticky 振った要素がそれはそれは見事に素通りするわけです。
stickyが効かない理由
これは大きく2パターンあるようです。テーマのテンプレート次第ですが、このサイトのテーマ「賢威8」はバッチリ二つとも該当してました。やったぜ!
親要素の overflow: hidden;
親要素だけではなく、より上位の先祖要素のどれかでもoverflow: hidden;が使われていると、動作しないようです。バッチリ、メインコンテナに振られてました。
これがパターン1。
float組みのレイアウト
こっちはsticky自体は実は効いてるんだけど、そもそも動く隙間がなかったというパターン。
画像のようにメインコンテンツはまだまだ下に続いていますが、サイドバーはここで要素が終わっています。
どうやら、stickyの場合fixedの場合と違い、要素が完全に浮いた状態になるワケではないようで、張り付くためのスペースが親要素に確保されている必要があるようです。
float組みのレイアウトではメインとサイドの「高さ」が揃わないことがネックになるようですね。
stickyが使えるようにする
前者は単純にoverflow: hidden が必要でなければ取り除けばいいのです。
が、問題は後者です。
解決法はとりあえず思いついたのは二つ。
flexを使う
親と高さ揃えるのは簡単で、display: flex; で一発なんですが、「いやー、そもそもそれ、割とテーマのレイアウトの根幹だし、関連した箇所で何らかの問題起こりそう」ってことで、ちょっと怖い。
サイドバーの要素の縦に引き延ばす
現実的に問題少なさそうなのはこっちかなーって、ぱっと思いついたんですが、ちょっと調べてみたところ、親要素の高さいっぱいまで広げるのって地味にちょっとめんどくさそう。
JQuery使えば簡単なんですけどね。それではちょっと負けた気がするので、意地でもCSSだけでやりたい(笑)
とりあえず、flexで片づけることにしました。
迷いに迷った挙句、どうしてもsticky使うことを諦められなくて、flexでやっちゃうことにしました。
以下、似たような境遇の方のために、解析→float組みをflexに改築、までの手順を紹介します。
とりあえず、当サイトのテーマ「賢威8」をモデルにしますが、ご自身のテーマでも同様の手順で調べればfloat→flexは可能ですので、是非挑戦してみてください。
まずは、要素の解析
クロームのデベロッパーツールを使います。
クロームデベロッパーツールの立ち上げ
出来る限り要素が何もなさそうなメインカラムの適当な位置で右クリック、”検証”を選択すると、デベロッパーツールが立ち上がります。
メインカラム、サイドカラムを探し、その親要素を見つける
Elementsタブのソースコードをマウスオーバーすると、触った要素が画面上で色が変わって表示されるので、メインカラムとサイドカラムを探します。
メインとサイドを見つけたら、更に「一段インデントが浅い要素」が親要素です。
flexはこの「親要素」に対して指定するプロパティです。
親要素にflexを付与
実際見つけた親要素はこれ。
<div class="keni-main_outer">...</div>
このクラスに対してflexを付与します。ついでに関連プロパティも二つ付与。
.keni-main_outer{ display: flex; flex-flow: row wrap; justify-content: space-between; }
軽く意味を解説すると、display: flex; がこの動作の本命。
flex-flowは、「並び方向」と「折り返しの有無」を一括で指定出来るプロパティです。今回はもちろん横並びかつ、折り返しあり、での指定。
justify-contentは要素の「スキマと並べ方」の調整です。今回は横に並んだ時に要素間のスペースを可能な限り取る、という指定をしています。
あと、「賢威8」の場合は、更に先祖要素にstickyを阻害するoverflow: hidden;が振られているので、それも取り除きます。
div.keni-container, div.keni-mv_wrap { overflow: unset; }
※ここから追記※
デベロッパーツールのレスポンシブモードで確認したら問題ないように感じたのですが、iPhoneでみたら思いっきり中身が右に向かってとびだしてました。修正はメインカラム、サイドバーそれぞれにmin-width: 0;を振ることで解決
#main,#secondary{ min-width: 0; }
※—–追記ここまで—–※
あとは上のCSSを適用させれば、あっという間に出来上がり。
サイドカラムの要素が下まで伸びきっているのを確認できると思います。
これで気持ちよーく”sticky”が張り付いてくれます。
まとめ
もともと振られていたfloatのプロパティは無効化しなくても影響ないように思いますので、これ以上いじっていません。
JQueryを使うパターンに比べてもかなり少ないコード量で実現可能ですね!ネチネチついてくるサイドバーを実現したい方は、是非参考にしてみてください!
コメント