最近のWEBデザインで使用頻度が高く、初学者が躓きやすいものに「position:sticky;」と「display:flex;」があります。(個人的な意見ですが・・・)
どちらもレスポンシブデザインでコーディングするには欠かせないもので、ポートフォリオから実践に移る時の最初の課題になる気がします。
特にposition:stickyの挙動としては、初学者の方がレスポンシブ対応しようとした時に泥沼にハマる罠もあるので合わせてご紹介します。
「position:sticky;」とは?
まずは簡単に「position:sticky;」がどういうものかご説明しておきます。
一言で言えば「relativeとfixedのいいとこどり」といったイメージで、要素が特定の位置に来るまではrelativeのように動き、一定の期間はfixedのように画面にとどまることができます。
「position:fixed;」の場合は画面全体に対して指定した位置に固定されますが、「poistion:sticky;」は親要素の中で位置が固定されます。
上のデモの場合、.sticky-contentの要素には「top:50px」と指定してあるので、画面がスクロールされて.sticky-contentがtop:50pxの位置に来たときにrelativeからfixedの挙動に変わります。
この時、cssとjsなどを使ってrelativeからfixedに変更すると親要素の高さが変わるなど、少し工夫しないとユーザービリティを損ないますがstickyであればデモのようにスムーズに切り替わります。
また、stickyは親要素の中だけで有効になるので、画面をさらにスクロールして親要素が画面から消える時には、.sticky-contentも親要素についていくようにスクロールします。(relativeの動きに戻ります)
どんな時に役立つのか
実務の中では主に下記のような箇所で使います。
- ヘッダー(グローバルメニュー)
- 追従サイドバー
- テーブルのth要素(もしくはthead)
もちろん他にも利用する場面は多くありますが、主な使い所は上記の3つだと思います。
特にヘッダーに関してはほぼ全てのWEBサイトにあり、最も利用頻度が高くなると思います。(stickyを使かどうかは要件次第ですが・・・)
レスポンシブを考えると表組みはあまり使わない方がいいと個人的には思いますが、どうしても必要なデータの場合はstickyをうまく使うことでデータのラベルが常に見えるのでわかりやすくなると思います。
ただし、スマホ場合はstickyで固定された要素によって、重要なデータが見えにくくなってしまう場合もあるので、使用する時にはデザイナーと相談した方がいいかもしれませんね。
【本題】「position:sticky;」が効かないとき
ここからが今日の本題。
初学者のみならず、普段からコーディングでご飯食べてる人でも陥ることのある「position:sticky;」が効かないパターンをいくつかご紹介していきます。
親要素・祖先要素に「overflow:hidden;」が使われている
これはかなり王道の罠で、「position:sticky;」が指定されている要素の親要素、もしくはそれよりも上の親要素に「overflow:hidden;」が指定されている場合です。
デモのように親要素に「overflow:hidden;」がある場合はわかりやすいのですが、祖先要素にある場合はなかなか原因を掴むことができないこともあります。
特に引き継ぎやリニューアルの場合は絶望することもあると思います。笑
また、デザインが少し凝っているものだと画像やイラストの配置をするためにbody要素やhtml要素に「overflow:hidden;」がかけられていることもあるので要チェックです。(スマホだけ、PCだけの時もある)
もしbody要素html要素に適用されている場合は、cssを変更したときに影響を与える範囲がかなり広くなるので、全体の念入りなチェックをするようにしましょう。
全体を把握するのが難しいような場合はstikyを使わずに対応できる方法などをデザイナーやディレクターと協議するのもありかもしれません。
「display:flex;」の子要素に「position:sticky;」を使う場合
サイドバーの追従など「display:flex;」で横並びにした要素に対して「position:sticky;」を使う場合は少し工夫が必要です。
というのも、「display:flex;」で横並びにしただけだとそれぞれの要素の高さが自動で親要素の高さと同じ高さに指定されます。
「position:sticky;」で固定する場合は固定する側の要素が、もう一方の要素よりも高さが小さくないと固定するための余白がないので動作していないように見えてしまいます。
デモを見ると左の要素には高さを指定していないのに、右の要素と同じ高さになっているのがわかります。
これを解決するためには親要素(flex-box)に「align-items:flex-start;」を指定します。
たったのこれだけで動くようになりました。
今回は「position:sticky;」を動かすために「align-items:flex-start;」をつけましたが、高さをそれぞれの要素に合わせた可変にした横並び(ブログ記事一覧など)の時にも使えるテクニックなので、必ず覚えておきましょう。
「position:sticky;」の要素に位置(top,right,bottom,left)が指定されていない
「position:sticky;」を使うためには、どの位置に固定をするのかを明示する必要があり、absoluteやfixedを使う時と同様に「top,right,bottom,left」で指定します。
通常は縦スクロールなのでtop,bottomで指定しますが、横スクロールで左側固定したい場合はleft、右側に固定したい場合はrightを使うことで固定することができます。
まとめ
今回は「position:sticky;」の思わぬ罠ということでいくつか例をご紹介しました。
慣れてくれば実際の表示画面を見ることである程度原因が想像できたりしますが、慣れるまでは一つ一つコードをチェックして原因を探ってみましょう。
メンターがいる方などは質問すればすぐに答えを教えてもらえるかもしれませんが、コーダー、フロントエンドとして実力を高めるためには自分で原因を見つける癖をつける必要があります。
コーディング自体は少し勉強すれば誰にでもできることですが、エラーが起きた時に解決できるかどうかが実力の差です。
ブラウザの開発ツールなどを駆使して時間の許す限りエラーと向き合いましょう。(納期は絶対守る)